Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | const charset = "EUC-JP"; |
michael@0 | 2 | const ScriptableUnicodeConverter = |
michael@0 | 3 | Components.Constructor("@mozilla.org/intl/scriptableunicodeconverter", |
michael@0 | 4 | "nsIScriptableUnicodeConverter"); |
michael@0 | 5 | var gConverter; |
michael@0 | 6 | |
michael@0 | 7 | function error(inString, outString, msg){ |
michael@0 | 8 | var dispIn = ""; |
michael@0 | 9 | var dispOut = ""; |
michael@0 | 10 | var i; |
michael@0 | 11 | for (i = 0; i < inString.length; ++i) { |
michael@0 | 12 | dispIn += " x" + inString.charCodeAt(i).toString(16); |
michael@0 | 13 | } |
michael@0 | 14 | if (outString.length == 0) { |
michael@0 | 15 | dispOut = "<empty>"; |
michael@0 | 16 | } else { |
michael@0 | 17 | for (i = 0; i < outString.length; ++i) { |
michael@0 | 18 | dispOut += " x" + outString.charCodeAt(i).toString(16); |
michael@0 | 19 | } |
michael@0 | 20 | } |
michael@0 | 21 | dump("\"" + dispIn + "\" ==> \"" + dispOut + "\"\n"); |
michael@0 | 22 | do_throw("security risk: " + msg); |
michael@0 | 23 | } |
michael@0 | 24 | |
michael@0 | 25 | function test(inString) { |
michael@0 | 26 | var outString = gConverter.ConvertToUnicode(inString) + |
michael@0 | 27 | gConverter.Finish(); |
michael@0 | 28 | |
michael@0 | 29 | switch (outString.length) { |
michael@0 | 30 | case 0: |
michael@0 | 31 | case 1: |
michael@0 | 32 | case 2: |
michael@0 | 33 | error(inString, outString, "Unexpected error"); |
michael@0 | 34 | break; |
michael@0 | 35 | case 3: |
michael@0 | 36 | error(inString, outString, "3 byte sequence eaten"); |
michael@0 | 37 | break; |
michael@0 | 38 | case 4: |
michael@0 | 39 | if (outString.charCodeAt(0) < 0x80 && |
michael@0 | 40 | outString.charCodeAt(1) < 0x80 && |
michael@0 | 41 | outString.charCodeAt(2) < 0x80 && |
michael@0 | 42 | outString.charCodeAt(3) < 0x80) { |
michael@0 | 43 | error(inString, outString, |
michael@0 | 44 | "3 byte sequence converted to 1 ASCII"); |
michael@0 | 45 | } |
michael@0 | 46 | break; |
michael@0 | 47 | case 5: |
michael@0 | 48 | if (outString != inString && |
michael@0 | 49 | outString.charCodeAt(0) < 0x80 && |
michael@0 | 50 | outString.charCodeAt(1) < 0x80 && |
michael@0 | 51 | outString.charCodeAt(2) < 0x80 && |
michael@0 | 52 | outString.charCodeAt(3) < 0x80 && |
michael@0 | 53 | outString.charCodeAt(4) < 0x80) { |
michael@0 | 54 | error(inString, outString, |
michael@0 | 55 | "3 byte sequence converted to 2 ASCII"); |
michael@0 | 56 | } |
michael@0 | 57 | break; |
michael@0 | 58 | case 6: |
michael@0 | 59 | if (outString != inString && |
michael@0 | 60 | outString.charCodeAt(0) < 0x80 && |
michael@0 | 61 | outString.charCodeAt(1) < 0x80 && |
michael@0 | 62 | outString.charCodeAt(2) < 0x80 && |
michael@0 | 63 | outString.charCodeAt(3) < 0x80 && |
michael@0 | 64 | outString.charCodeAt(4) < 0x80 && |
michael@0 | 65 | outString.charCodeAt(5) < 0x80) { |
michael@0 | 66 | error(inString, outString, |
michael@0 | 67 | "3 byte sequence converted to 3 ASCII"); |
michael@0 | 68 | } |
michael@0 | 69 | break; |
michael@0 | 70 | } |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | function run_test() { |
michael@0 | 74 | gConverter = new ScriptableUnicodeConverter(); |
michael@0 | 75 | gConverter.charset = charset; |
michael@0 | 76 | |
michael@0 | 77 | var byte1, byte2, byte3; |
michael@0 | 78 | for (byte1 = 1; byte1 < 0x100; ++byte1) { |
michael@0 | 79 | for (byte2 = 1; byte2 < 0x100; ++byte2) { |
michael@0 | 80 | if (byte1 == 0x8f) { |
michael@0 | 81 | for (byte3 = 1; byte3 < 0x100; ++byte3) { |
michael@0 | 82 | test(String.fromCharCode(byte1, byte2, byte3) + "foo"); |
michael@0 | 83 | } |
michael@0 | 84 | } else { |
michael@0 | 85 | test(String.fromCharCode(byte1, byte2) + " foo"); |
michael@0 | 86 | } |
michael@0 | 87 | } |
michael@0 | 88 | } |
michael@0 | 89 | } |