Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | #define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) |
michael@0 | 2 | #define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) |
michael@0 | 3 | #include <stddef.h> |
michael@0 | 4 | |
michael@0 | 5 | struct MOZ_NONHEAP_CLASS NonHeap { |
michael@0 | 6 | int i; |
michael@0 | 7 | void *operator new(size_t x) { return 0; } |
michael@0 | 8 | void *operator new(size_t blah, char *buffer) { return buffer; } |
michael@0 | 9 | }; |
michael@0 | 10 | |
michael@0 | 11 | template <class T> |
michael@0 | 12 | struct MOZ_NONHEAP_CLASS TemplateClass { |
michael@0 | 13 | T i; |
michael@0 | 14 | }; |
michael@0 | 15 | |
michael@0 | 16 | void gobble(void *) { } |
michael@0 | 17 | |
michael@0 | 18 | void misuseNonHeapClass(int len) { |
michael@0 | 19 | NonHeap valid; |
michael@0 | 20 | NonHeap alsoValid[2]; |
michael@0 | 21 | static NonHeap validStatic; |
michael@0 | 22 | static NonHeap alsoValidStatic[2]; |
michael@0 | 23 | |
michael@0 | 24 | gobble(&valid); |
michael@0 | 25 | gobble(&validStatic); |
michael@0 | 26 | gobble(&alsoValid[0]); |
michael@0 | 27 | |
michael@0 | 28 | gobble(new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} |
michael@0 | 29 | gobble(new NonHeap[10]); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} |
michael@0 | 30 | gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' is not valid on the heap}} |
michael@0 | 31 | gobble(len <= 5 ? &valid : new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}} |
michael@0 | 32 | |
michael@0 | 33 | char buffer[sizeof(NonHeap)]; |
michael@0 | 34 | gobble(new (buffer) NonHeap); |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | NonHeap validStatic; |
michael@0 | 38 | struct RandomClass { |
michael@0 | 39 | NonHeap nonstaticMember; // expected-note {{'RandomClass' is a non-heap class because member 'nonstaticMember' is a non-heap class 'NonHeap'}} |
michael@0 | 40 | static NonHeap staticMember; |
michael@0 | 41 | }; |
michael@0 | 42 | struct MOZ_NONHEAP_CLASS RandomNonHeapClass { |
michael@0 | 43 | NonHeap nonstaticMember; |
michael@0 | 44 | static NonHeap staticMember; |
michael@0 | 45 | }; |
michael@0 | 46 | |
michael@0 | 47 | struct BadInherit : NonHeap {}; // expected-note {{'BadInherit' is a non-heap class because it inherits from a non-heap class 'NonHeap'}} |
michael@0 | 48 | struct MOZ_NONHEAP_CLASS GoodInherit : NonHeap {}; |
michael@0 | 49 | |
michael@0 | 50 | void useStuffWrongly() { |
michael@0 | 51 | gobble(new BadInherit); // expected-error {{variable of type 'BadInherit' is not valid on the heap}} |
michael@0 | 52 | gobble(new RandomClass); // expected-error {{variable of type 'RandomClass' is not valid on the heap}} |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | // Stack class overrides non-heap classes. |
michael@0 | 56 | struct MOZ_STACK_CLASS StackClass {}; |
michael@0 | 57 | struct MOZ_NONHEAP_CLASS InferredStackClass : GoodInherit { |
michael@0 | 58 | NonHeap nonstaticMember; |
michael@0 | 59 | StackClass stackClass; // expected-note {{'InferredStackClass' is a stack class because member 'stackClass' is a stack class 'StackClass'}} |
michael@0 | 60 | }; |
michael@0 | 61 | |
michael@0 | 62 | InferredStackClass global; // expected-error {{variable of type 'InferredStackClass' only valid on the stack}} |