1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23// Verify that the string decoder works getting 1 byte at a time, 24// the whole buffer at once, and that both match the .toString(enc) 25// result of the entire buffer. 26 27require('../common'); 28const assert = require('assert'); 29const SD = require('string_decoder').StringDecoder; 30const encodings = ['base64', 'base64url', 'hex', 'utf8', 'utf16le', 'ucs2']; 31 32const bufs = [ '☃��', 'asdf' ].map((b) => Buffer.from(b)); 33 34// Also test just arbitrary bytes from 0-15. 35for (let i = 1; i <= 16; i++) { 36 const bytes = '.'.repeat(i - 1).split('.').map((_, j) => j + 0x78); 37 bufs.push(Buffer.from(bytes)); 38} 39 40encodings.forEach(testEncoding); 41 42testEnd('utf8', Buffer.of(0xE2), Buffer.of(0x61), '\uFFFDa'); 43testEnd('utf8', Buffer.of(0xE2), Buffer.of(0x82), '\uFFFD\uFFFD'); 44testEnd('utf8', Buffer.of(0xE2), Buffer.of(0xE2), '\uFFFD\uFFFD'); 45testEnd('utf8', Buffer.of(0xE2, 0x82), Buffer.of(0x61), '\uFFFDa'); 46testEnd('utf8', Buffer.of(0xE2, 0x82), Buffer.of(0xAC), '\uFFFD\uFFFD'); 47testEnd('utf8', Buffer.of(0xE2, 0x82), Buffer.of(0xE2), '\uFFFD\uFFFD'); 48testEnd('utf8', Buffer.of(0xE2, 0x82, 0xAC), Buffer.of(0x61), '€a'); 49 50testEnd('utf16le', Buffer.of(0x3D), Buffer.of(0x61, 0x00), 'a'); 51testEnd('utf16le', Buffer.of(0x3D), Buffer.of(0xD8, 0x4D, 0xDC), '\u4DD8'); 52testEnd('utf16le', Buffer.of(0x3D, 0xD8), Buffer.of(), '\uD83D'); 53testEnd('utf16le', Buffer.of(0x3D, 0xD8), Buffer.of(0x61, 0x00), '\uD83Da'); 54testEnd( 55 'utf16le', 56 Buffer.of(0x3D, 0xD8), 57 Buffer.of(0x4D, 0xDC), 58 '\uD83D\uDC4D' 59); 60testEnd('utf16le', Buffer.of(0x3D, 0xD8, 0x4D), Buffer.of(), '\uD83D'); 61testEnd( 62 'utf16le', 63 Buffer.of(0x3D, 0xD8, 0x4D), 64 Buffer.of(0x61, 0x00), 65 '\uD83Da' 66); 67testEnd('utf16le', Buffer.of(0x3D, 0xD8, 0x4D), Buffer.of(0xDC), '\uD83D'); 68testEnd( 69 'utf16le', 70 Buffer.of(0x3D, 0xD8, 0x4D, 0xDC), 71 Buffer.of(0x61, 0x00), 72 '��a' 73); 74 75testEnd('base64', Buffer.of(0x61), Buffer.of(), 'YQ=='); 76testEnd('base64', Buffer.of(0x61), Buffer.of(0x61), 'YQ==YQ=='); 77testEnd('base64', Buffer.of(0x61, 0x61), Buffer.of(), 'YWE='); 78testEnd('base64', Buffer.of(0x61, 0x61), Buffer.of(0x61), 'YWE=YQ=='); 79testEnd('base64', Buffer.of(0x61, 0x61, 0x61), Buffer.of(), 'YWFh'); 80testEnd('base64', Buffer.of(0x61, 0x61, 0x61), Buffer.of(0x61), 'YWFhYQ=='); 81 82testEnd('base64url', Buffer.of(0x61), Buffer.of(), 'YQ'); 83testEnd('base64url', Buffer.of(0x61), Buffer.of(0x61), 'YQYQ'); 84testEnd('base64url', Buffer.of(0x61, 0x61), Buffer.of(), 'YWE'); 85testEnd('base64url', Buffer.of(0x61, 0x61), Buffer.of(0x61), 'YWEYQ'); 86testEnd('base64url', Buffer.of(0x61, 0x61, 0x61), Buffer.of(), 'YWFh'); 87testEnd('base64url', Buffer.of(0x61, 0x61, 0x61), Buffer.of(0x61), 'YWFhYQ'); 88 89function testEncoding(encoding) { 90 bufs.forEach((buf) => { 91 testBuf(encoding, buf); 92 }); 93} 94 95function testBuf(encoding, buf) { 96 // Write one byte at a time. 97 let s = new SD(encoding); 98 let res1 = ''; 99 for (let i = 0; i < buf.length; i++) { 100 res1 += s.write(buf.slice(i, i + 1)); 101 } 102 res1 += s.end(); 103 104 // Write the whole buffer at once. 105 let res2 = ''; 106 s = new SD(encoding); 107 res2 += s.write(buf); 108 res2 += s.end(); 109 110 // .toString() on the buffer 111 const res3 = buf.toString(encoding); 112 113 // One byte at a time should match toString 114 assert.strictEqual(res1, res3); 115 // All bytes at once should match toString 116 assert.strictEqual(res2, res3); 117} 118 119function testEnd(encoding, incomplete, next, expected) { 120 let res = ''; 121 const s = new SD(encoding); 122 res += s.write(incomplete); 123 res += s.end(); 124 res += s.write(next); 125 res += s.end(); 126 127 assert.strictEqual(res, expected); 128} 129