test_chromeutils_base64.js (3428B)
1 "use strict"; 2 3 function run_test() { 4 test_base64URLEncode(); 5 test_base64URLDecode(); 6 } 7 8 // Test vectors from RFC 4648, section 10. 9 let textTests = { 10 "": "", 11 f: "Zg", 12 fo: "Zm8", 13 foo: "Zm9v", 14 foob: "Zm9vYg", 15 fooba: "Zm9vYmE", 16 foobar: "Zm9vYmFy", 17 }; 18 19 // Examples from RFC 4648, section 9. 20 let binaryTests = [ 21 { 22 decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]), 23 encoded: "FPucA9l-", 24 }, 25 { 26 decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9]), 27 encoded: "FPucA9k", 28 }, 29 { 30 decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03]), 31 encoded: "FPucAw", 32 }, 33 ]; 34 35 function padEncodedValue(value) { 36 switch (value.length % 4) { 37 case 0: 38 return value; 39 case 2: 40 return value + "=="; 41 case 3: 42 return value + "="; 43 default: 44 throw new TypeError("Invalid encoded value"); 45 } 46 } 47 48 function testEncode(input, encoded) { 49 equal( 50 ChromeUtils.base64URLEncode(input, { pad: false }), 51 encoded, 52 encoded + " without padding" 53 ); 54 equal( 55 ChromeUtils.base64URLEncode(input, { pad: true }), 56 padEncodedValue(encoded), 57 encoded + " with padding" 58 ); 59 } 60 61 function test_base64URLEncode() { 62 throws( 63 _ => ChromeUtils.base64URLEncode(new Uint8Array(0)), 64 /TypeError/, 65 "Should require encoding options" 66 ); 67 throws( 68 _ => ChromeUtils.base64URLEncode(new Uint8Array(0), {}), 69 /TypeError/, 70 "Encoding should require the padding option" 71 ); 72 73 for (let { decoded, encoded } of binaryTests) { 74 testEncode(decoded, encoded); 75 } 76 77 let textEncoder = new TextEncoder(); 78 for (let decoded of Object.keys(textTests)) { 79 let input = textEncoder.encode(decoded); 80 testEncode(input, textTests[decoded]); 81 } 82 } 83 84 function testDecode(input, decoded) { 85 let buffer = ChromeUtils.base64URLDecode(input, { padding: "reject" }); 86 deepEqual(new Uint8Array(buffer), decoded, input + " with padding rejected"); 87 88 let paddedValue = padEncodedValue(input); 89 buffer = ChromeUtils.base64URLDecode(paddedValue, { padding: "ignore" }); 90 deepEqual(new Uint8Array(buffer), decoded, input + " with padding ignored"); 91 92 if (paddedValue.length > input.length) { 93 throws( 94 _ => ChromeUtils.base64URLDecode(paddedValue, { padding: "reject" }), 95 /NS_ERROR_ILLEGAL_VALUE/, 96 paddedValue + " with padding rejected should throw" 97 ); 98 99 throws( 100 _ => ChromeUtils.base64URLDecode(input, { padding: "require" }), 101 /NS_ERROR_ILLEGAL_VALUE/, 102 input + " with padding required should throw" 103 ); 104 105 buffer = ChromeUtils.base64URLDecode(paddedValue, { padding: "require" }); 106 deepEqual( 107 new Uint8Array(buffer), 108 decoded, 109 paddedValue + " with padding required" 110 ); 111 } 112 } 113 114 function test_base64URLDecode() { 115 throws( 116 _ => ChromeUtils.base64URLDecode(""), 117 /TypeError/, 118 "Should require decoding options" 119 ); 120 throws( 121 _ => ChromeUtils.base64URLDecode("", {}), 122 /TypeError/, 123 "Decoding should require the padding option" 124 ); 125 throws( 126 _ => ChromeUtils.base64URLDecode("", { padding: "chocolate" }), 127 /TypeError/, 128 "Decoding should throw for invalid padding policy" 129 ); 130 131 for (let { decoded, encoded } of binaryTests) { 132 testDecode(encoded, decoded); 133 } 134 135 let textEncoder = new TextEncoder(); 136 for (let decoded of Object.keys(textTests)) { 137 let expectedBuffer = textEncoder.encode(decoded); 138 testDecode(textTests[decoded], expectedBuffer); 139 } 140 }