|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | 3 | var defineProperties = require('define-properties'); |
| 4 | +var forEach = require('for-each'); |
| 5 | +var getProto = require('es-abstract/helpers/getProto'); |
| 6 | +var inspect = require('object-inspect'); |
4 | 7 | var test = require('tape'); |
5 | 8 |
|
6 | 9 | var index = require('../Uint8Array.fromBase64'); |
@@ -78,6 +81,234 @@ module.exports = { |
78 | 81 | 'base64url string with base64 alphabet throws' |
79 | 82 | ); |
80 | 83 |
|
| 84 | + st.test('test262: test/built-ins/Uint8Array/fromBase64/alphabet.js', function (s2t) { |
| 85 | + s2t.deepEqual(method('x+/y'), new Uint8Array([199, 239, 242])); |
| 86 | + s2t.deepEqual(method('x+/y', { alphabet: 'base64' }), new Uint8Array([199, 239, 242])); |
| 87 | + s2t['throws']( |
| 88 | + function () { |
| 89 | + method('x+/y', { alphabet: 'base64url' }); |
| 90 | + }, |
| 91 | + SyntaxError |
| 92 | + ); |
| 93 | + |
| 94 | + s2t.deepEqual(method('x-_y', { alphabet: 'base64url' }), new Uint8Array([199, 239, 242])); |
| 95 | + s2t['throws']( |
| 96 | + function () { method('x-_y'); }, |
| 97 | + SyntaxError |
| 98 | + ); |
| 99 | + s2t['throws']( |
| 100 | + function () { method('x-_y', { alphabet: 'base64' }); }, |
| 101 | + SyntaxError |
| 102 | + ); |
| 103 | + |
| 104 | + s2t.end(); |
| 105 | + }); |
| 106 | + |
| 107 | + var illegal = [ |
| 108 | + 'Zm.9v', |
| 109 | + 'Zm9v^', |
| 110 | + 'Zg==&', |
| 111 | + 'Z\u2212==', // U+2212 'Minus Sign' |
| 112 | + 'Z\uFF0B==', // U+FF0B 'Fullwidth Plus Sign' |
| 113 | + 'Zg\u00A0==', // nbsp |
| 114 | + 'Zg\u2009==', // thin space |
| 115 | + 'Zg\u2028==' // line separator |
| 116 | + ]; |
| 117 | + forEach(illegal, function (value) { |
| 118 | + st['throws']( |
| 119 | + function () { method(value); }, |
| 120 | + SyntaxError, |
| 121 | + inspect(value) + ' throws SyntaxError' |
| 122 | + ); |
| 123 | + }); |
| 124 | + |
| 125 | + st.test('test262: test/built-ins/Uint8Array/fromBase64/last-chunk-handling.js', function (s2t) { |
| 126 | + // padding |
| 127 | + s2t.deepEqual(method('ZXhhZg=='), new Uint8Array([101, 120, 97, 102])); |
| 128 | + s2t.deepEqual(method('ZXhhZg==', { lastChunkHandling: 'loose' }), new Uint8Array([101, 120, 97, 102])); |
| 129 | + s2t.deepEqual(method('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' }), new Uint8Array([101, 120, 97, 102])); |
| 130 | + s2t.deepEqual(method('ZXhhZg==', { lastChunkHandling: 'strict' }), new Uint8Array([101, 120, 97, 102])); |
| 131 | + |
| 132 | + // no padding |
| 133 | + s2t.deepEqual(method('ZXhhZg'), new Uint8Array([101, 120, 97, 102])); |
| 134 | + s2t.deepEqual(method('ZXhhZg', { lastChunkHandling: 'loose' }), new Uint8Array([101, 120, 97, 102])); |
| 135 | + s2t.deepEqual(method('ZXhhZg', { lastChunkHandling: 'stop-before-partial' }), new Uint8Array([101, 120, 97])); |
| 136 | + s2t['throws']( |
| 137 | + function () { method('ZXhhZg', { lastChunkHandling: 'strict' }); }, |
| 138 | + SyntaxError |
| 139 | + ); |
| 140 | + |
| 141 | + // non-zero padding bits |
| 142 | + s2t.deepEqual(method('ZXhhZh=='), new Uint8Array([101, 120, 97, 102])); |
| 143 | + s2t.deepEqual(method('ZXhhZh==', { lastChunkHandling: 'loose' }), new Uint8Array([101, 120, 97, 102])); |
| 144 | + s2t.deepEqual(method('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' }), new Uint8Array([101, 120, 97, 102])); |
| 145 | + s2t['throws']( |
| 146 | + function () { method('ZXhhZh==', { lastChunkHandling: 'strict' }); }, |
| 147 | + SyntaxError |
| 148 | + ); |
| 149 | + |
| 150 | + // non-zero padding bits, no padding |
| 151 | + s2t.deepEqual(method('ZXhhZh'), new Uint8Array([101, 120, 97, 102])); |
| 152 | + s2t.deepEqual(method('ZXhhZh', { lastChunkHandling: 'loose' }), new Uint8Array([101, 120, 97, 102])); |
| 153 | + s2t.deepEqual(method('ZXhhZh', { lastChunkHandling: 'stop-before-partial' }), new Uint8Array([101, 120, 97])); |
| 154 | + s2t['throws']( |
| 155 | + function () { method('ZXhhZh', { lastChunkHandling: 'strict' }); }, |
| 156 | + SyntaxError |
| 157 | + ); |
| 158 | + |
| 159 | + // malformed padding |
| 160 | + s2t['throws']( |
| 161 | + function () { method('ZXhhZg='); }, |
| 162 | + SyntaxError |
| 163 | + ); |
| 164 | + s2t['throws']( |
| 165 | + function () { method('ZXhhZg=', { lastChunkHandling: 'loose' }); }, |
| 166 | + SyntaxError |
| 167 | + ); |
| 168 | + s2t.deepEqual(method('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' }), new Uint8Array([101, 120, 97])); |
| 169 | + s2t['throws']( |
| 170 | + function () { method('ZXhhZg=', { lastChunkHandling: 'strict' }); }, |
| 171 | + SyntaxError |
| 172 | + ); |
| 173 | + |
| 174 | + s2t.end(); |
| 175 | + }); |
| 176 | + |
| 177 | + st.test('test262: test/built-ins/Uint8Array/fromBase64/option-coercion.js', function (s2t) { |
| 178 | + var throwyToString = {}; |
| 179 | + var results = s2t.intercept( |
| 180 | + throwyToString, |
| 181 | + 'toString', |
| 182 | + { value: function () { throw new EvalError('toString called'); } } |
| 183 | + ); |
| 184 | + |
| 185 | + s2t['throws']( |
| 186 | + function () { method('Zg==', { alphabet: throwyToString }); }, |
| 187 | + TypeError |
| 188 | + ); |
| 189 | + s2t.deepEqual(results(), []); |
| 190 | + |
| 191 | + s2t['throws']( |
| 192 | + function () { method('Zg==', { lastChunkHandling: throwyToString }); }, |
| 193 | + TypeError |
| 194 | + ); |
| 195 | + s2t.deepEqual(results(), []); |
| 196 | + |
| 197 | + s2t.test('getters', { skip: !defineProperties.supportsDescriptors }, function (s3t) { |
| 198 | + var base64UrlOptions = {}; |
| 199 | + var alphabetResults = s3t.intercept(base64UrlOptions, 'alphabet', { get: function () { return 'base64url'; } }); |
| 200 | + |
| 201 | + var arr = method('x-_y', base64UrlOptions); |
| 202 | + s3t.deepEqual(arr, new Uint8Array([199, 239, 242])); |
| 203 | + s3t.deepEqual(alphabetResults(), [ |
| 204 | + { |
| 205 | + type: 'get', |
| 206 | + success: true, |
| 207 | + value: 'base64url', |
| 208 | + args: [], |
| 209 | + receiver: base64UrlOptions |
| 210 | + } |
| 211 | + ]); |
| 212 | + |
| 213 | + var strictOptions = {}; |
| 214 | + var strictResults = s3t.intercept(strictOptions, 'lastChunkHandling', { get: function () { return 'strict'; } }); |
| 215 | + |
| 216 | + var arr2 = method('Zg==', strictOptions); |
| 217 | + s3t.deepEqual(arr2, new Uint8Array([102])); |
| 218 | + s3t.deepEqual(strictResults(), [ |
| 219 | + { |
| 220 | + type: 'get', |
| 221 | + success: true, |
| 222 | + value: 'strict', |
| 223 | + args: [], |
| 224 | + receiver: strictOptions |
| 225 | + } |
| 226 | + ]); |
| 227 | + |
| 228 | + s3t.end(); |
| 229 | + }); |
| 230 | + |
| 231 | + s2t.end(); |
| 232 | + }); |
| 233 | + |
| 234 | + st.test('test262: test/built-ins/Uint8Array/fromBase64/results.js', function (s2t) { |
| 235 | + // standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 |
| 236 | + var standardBase64Vectors = [ |
| 237 | + ['', []], |
| 238 | + ['Zg==', [102]], |
| 239 | + ['Zm8=', [102, 111]], |
| 240 | + ['Zm9v', [102, 111, 111]], |
| 241 | + ['Zm9vYg==', [102, 111, 111, 98]], |
| 242 | + ['Zm9vYmE=', [102, 111, 111, 98, 97]], |
| 243 | + ['Zm9vYmFy', [102, 111, 111, 98, 97, 114]] |
| 244 | + ]; |
| 245 | + |
| 246 | + forEach(standardBase64Vectors, function (pair) { |
| 247 | + var arr = method(pair[0]); |
| 248 | + s2t.equal(getProto(arr), Uint8Array.prototype, 'decoding ' + pair[0]); |
| 249 | + s2t.deepEqual(arr, new Uint8Array(pair[1]), 'decoding ' + pair[0]); |
| 250 | + }); |
| 251 | + |
| 252 | + s2t.end(); |
| 253 | + }); |
| 254 | + |
| 255 | + st.test('test262: test/built-ins/Uint8Array/fromBase64/string-coercion.js', function (s2t) { |
| 256 | + var throwyToString = {}; |
| 257 | + var toStringResults = s2t.intercept( |
| 258 | + throwyToString, |
| 259 | + 'toString', |
| 260 | + { value: function () { throw new EvalError('toString called'); } } |
| 261 | + ); |
| 262 | + |
| 263 | + s2t['throws']( |
| 264 | + function () { method(throwyToString); }, |
| 265 | + TypeError |
| 266 | + ); |
| 267 | + s2t.deepEqual(toStringResults(), []); |
| 268 | + |
| 269 | + s2t.test('getters', { skip: !defineProperties.supportsDescriptors }, function (s3t) { |
| 270 | + var touchyOptions = {}; |
| 271 | + var alphaResults = s3t.intercept( |
| 272 | + touchyOptions, |
| 273 | + 'alphabet', |
| 274 | + { get: function () { throw new EvalError('alphabet accessed'); } } |
| 275 | + ); |
| 276 | + var lastChunkResults = s3t.intercept( |
| 277 | + touchyOptions, |
| 278 | + 'lastChunkHandling', |
| 279 | + { get: function () { throw new EvalError('alphabet accessed'); } } |
| 280 | + ); |
| 281 | + |
| 282 | + s3t['throws']( |
| 283 | + function () { method(throwyToString, touchyOptions); }, |
| 284 | + TypeError |
| 285 | + ); |
| 286 | + s3t.deepEqual(toStringResults(), []); |
| 287 | + s3t.deepEqual(alphaResults(), []); |
| 288 | + s3t.deepEqual(lastChunkResults(), []); |
| 289 | + |
| 290 | + s3t.end(); |
| 291 | + }); |
| 292 | + |
| 293 | + s2t.end(); |
| 294 | + }); |
| 295 | + |
| 296 | + st.test('test262: test/built-ins/Uint8Array/fromBase64/whitespace.js', function (s2t) { |
| 297 | + var whitespaceKinds = [ |
| 298 | + ['Z g==', 'space'], |
| 299 | + ['Z\tg==', 'tab'], |
| 300 | + ['Z\x0Ag==', 'LF'], |
| 301 | + ['Z\x0Cg==', 'FF'], |
| 302 | + ['Z\x0Dg==', 'CR'] |
| 303 | + ]; |
| 304 | + forEach(whitespaceKinds, function (pair) { |
| 305 | + var arr = method(pair[0]); |
| 306 | + s2t.deepEqual(arr, new Uint8Array([102]), 'ascii whitespace: ' + pair[1]); |
| 307 | + }); |
| 308 | + |
| 309 | + s2t.end(); |
| 310 | + }); |
| 311 | + |
81 | 312 | st.end(); |
82 | 313 | }); |
83 | 314 | }, |
|
0 commit comments