Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 4 | |
michael@0 | 5 | from __future__ import print_function, unicode_literals |
michael@0 | 6 | |
michael@0 | 7 | import re |
michael@0 | 8 | |
michael@0 | 9 | class OutputHandler(object): |
michael@0 | 10 | ''' |
michael@0 | 11 | A class for handling Valgrind output. |
michael@0 | 12 | |
michael@0 | 13 | Valgrind errors look like this: |
michael@0 | 14 | |
michael@0 | 15 | ==60741== 40 (24 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 2,746 of 5,235 |
michael@0 | 16 | ==60741== at 0x4C26B43: calloc (vg_replace_malloc.c:593) |
michael@0 | 17 | ==60741== by 0x63AEF65: PR_Calloc (prmem.c:443) |
michael@0 | 18 | ==60741== by 0x69F236E: PORT_ZAlloc_Util (secport.c:117) |
michael@0 | 19 | ==60741== by 0x69F1336: SECITEM_AllocItem_Util (secitem.c:28) |
michael@0 | 20 | ==60741== by 0xA04280B: ffi_call_unix64 (in /builds/slave/m-in-l64-valgrind-000000000000/objdir/toolkit/library/libxul.so) |
michael@0 | 21 | ==60741== by 0xA042443: ffi_call (ffi64.c:485) |
michael@0 | 22 | |
michael@0 | 23 | For each such error, this class extracts most or all of the first (error |
michael@0 | 24 | kind) line, plus the function name in each of the first few stack entries. |
michael@0 | 25 | With this data it constructs and prints a TEST-UNEXPECTED-FAIL message that |
michael@0 | 26 | TBPL will highlight. |
michael@0 | 27 | |
michael@0 | 28 | It buffers these lines from which text is extracted so that the |
michael@0 | 29 | TEST-UNEXPECTED-FAIL message can be printed before the full error. |
michael@0 | 30 | |
michael@0 | 31 | Parsing the Valgrind output isn't ideal, and it may break in the future if |
michael@0 | 32 | Valgrind changes the format of the messages, or introduces new error kinds. |
michael@0 | 33 | To protect against this, we also count how many lines containing |
michael@0 | 34 | "<insert_a_suppression_name_here>" are seen. Thanks to the use of |
michael@0 | 35 | --gen-suppressions=yes, exactly one of these lines is present per error. If |
michael@0 | 36 | the count of these lines doesn't match the error count found during |
michael@0 | 37 | parsing, then the parsing has missed one or more errors and we can fail |
michael@0 | 38 | appropriately. |
michael@0 | 39 | ''' |
michael@0 | 40 | |
michael@0 | 41 | def __init__(self): |
michael@0 | 42 | # The regexps in this list match all of Valgrind's errors. Note that |
michael@0 | 43 | # Valgrind is English-only, so we don't have to worry about |
michael@0 | 44 | # localization. |
michael@0 | 45 | self.re_error = \ |
michael@0 | 46 | r'==\d+== (' + \ |
michael@0 | 47 | r'(Use of uninitialised value of size \d+)|' + \ |
michael@0 | 48 | r'(Conditional jump or move depends on uninitialised value\(s\))|' + \ |
michael@0 | 49 | r'(Syscall param .* contains uninitialised byte\(s\))|' + \ |
michael@0 | 50 | r'(Syscall param .* points to (unaddressable|uninitialised) byte\(s\))|' + \ |
michael@0 | 51 | r'((Unaddressable|Uninitialised) byte\(s\) found during client check request)|' + \ |
michael@0 | 52 | r'(Invalid free\(\) / delete / delete\[\] / realloc\(\))|' + \ |
michael@0 | 53 | r'(Mismatched free\(\) / delete / delete \[\])|' + \ |
michael@0 | 54 | r'(Invalid (read|write) of size \d+)|' + \ |
michael@0 | 55 | r'(Jump to the invalid address stated on the next line)|' + \ |
michael@0 | 56 | r'(Source and destination overlap in .*)|' + \ |
michael@0 | 57 | r'(.* bytes in .* blocks are .* lost)' + \ |
michael@0 | 58 | r')' |
michael@0 | 59 | # Match identifer chars, plus ':' for namespaces, and '\?' in order to |
michael@0 | 60 | # match "???" which Valgrind sometimes produces. |
michael@0 | 61 | self.re_stack_entry = r'^==\d+==.*0x[A-Z0-9]+: ([A-Za-z0-9_:\?]+)' |
michael@0 | 62 | self.re_suppression = r' *<insert_a_suppression_name_here>' |
michael@0 | 63 | self.error_count = 0 |
michael@0 | 64 | self.suppression_count = 0 |
michael@0 | 65 | self.number_of_stack_entries_to_get = 0 |
michael@0 | 66 | self.curr_failure_msg = None |
michael@0 | 67 | self.buffered_lines = None |
michael@0 | 68 | |
michael@0 | 69 | def __call__(self, line): |
michael@0 | 70 | if self.number_of_stack_entries_to_get == 0: |
michael@0 | 71 | # Look for the start of a Valgrind error. |
michael@0 | 72 | m = re.search(self.re_error, line) |
michael@0 | 73 | if m: |
michael@0 | 74 | self.error_count += 1 |
michael@0 | 75 | self.number_of_stack_entries_to_get = 4 |
michael@0 | 76 | self.curr_failure_msg = 'TEST-UNEXPECTED-FAIL | valgrind-test | ' + m.group(1) + " at " |
michael@0 | 77 | self.buffered_lines = [line] |
michael@0 | 78 | else: |
michael@0 | 79 | print(line) |
michael@0 | 80 | |
michael@0 | 81 | else: |
michael@0 | 82 | # We've recently found a Valgrind error, and are now extracting |
michael@0 | 83 | # details from the first few stack entries. |
michael@0 | 84 | self.buffered_lines.append(line) |
michael@0 | 85 | m = re.match(self.re_stack_entry, line) |
michael@0 | 86 | if m: |
michael@0 | 87 | self.curr_failure_msg += m.group(1) |
michael@0 | 88 | else: |
michael@0 | 89 | self.curr_failure_msg += '?!?' |
michael@0 | 90 | |
michael@0 | 91 | self.number_of_stack_entries_to_get -= 1 |
michael@0 | 92 | if self.number_of_stack_entries_to_get != 0: |
michael@0 | 93 | self.curr_failure_msg += ' / ' |
michael@0 | 94 | else: |
michael@0 | 95 | # We've finished getting the first few stack entries. Print the |
michael@0 | 96 | # failure message and the buffered lines, and then reset state. |
michael@0 | 97 | print('\n' + self.curr_failure_msg + '\n') |
michael@0 | 98 | for b in self.buffered_lines: |
michael@0 | 99 | print(b) |
michael@0 | 100 | self.curr_failure_msg = None |
michael@0 | 101 | self.buffered_lines = None |
michael@0 | 102 | |
michael@0 | 103 | if re.match(self.re_suppression, line): |
michael@0 | 104 | self.suppression_count += 1 |
michael@0 | 105 |