Skip to content

Commit ea6f500

Browse files
committed
test: add legacyHookDecode tests
1 parent 51bc0b2 commit ea6f500

2 files changed

Lines changed: 51 additions & 3 deletions

File tree

fallback/encoding.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,18 @@ export function legacyHookDecode(input, fallbackEncoding) {
265265
const bomEncoding = getBOMEncoding(u8)
266266
if (bomEncoding) u8 = u8.subarray(bomEncoding === 'utf-8' ? 3 : 2)
267267
const enc = bomEncoding ?? fallbackEncoding ?? 'utf-8' // "the byte order mark is more authoritative than anything else"
268+
268269
if (enc === 'utf-8') return utf8toStringLoose(u8)
269-
if (enc === 'utf-16le') return utf16toStringLoose(u8, 'uint8-le')
270-
if (enc === 'utf-16be') return utf16toStringLoose(u8, 'uint8-be')
270+
if (enc === 'utf-16le' || enc === 'utf-16be') {
271+
let suffix = ''
272+
if (u8.byteLength % 2 !== 0) {
273+
suffix = replacementChar
274+
u8 = u8.subarray(0, -1)
275+
}
276+
277+
return utf16toStringLoose(u8, enc === 'utf-16le' ? 'uint8-le' : 'uint8-be') + suffix
278+
}
279+
271280
if (!Object.hasOwn(labels, enc)) throw new RangeError(E_ENCODING)
272281

273282
if (multibyteSet.has(enc)) {

tests/encoding/generic.test.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { TextDecoder, TextEncoder, getBOMEncoding } from '@exodus/bytes/encoding.js'
1+
import {
2+
TextDecoder,
3+
TextEncoder,
4+
getBOMEncoding,
5+
legacyHookDecode,
6+
} from '@exodus/bytes/encoding.js'
27
import { fromHex } from '@exodus/bytes/hex.js'
38
import { test, describe } from 'node:test'
49
import unfinishedBytesFixtures from '../fixtures/text-encoding.unfinishedBytes.js'
@@ -83,6 +88,40 @@ describe('encodings are ASCII supersets, except utf-16 and iso-2022-jp', () => {
8388
}
8489
})
8590

91+
describe('legacyHookDecode', () => {
92+
const fixtures = {
93+
replacement: [
94+
['', ''],
95+
['00', '\uFFFD'],
96+
['ff', '\uFFFD'],
97+
['20', '\uFFFD'],
98+
['2020', '\uFFFD'],
99+
// BOM takes preference
100+
['efbbbf', ''],
101+
['efbbbf2a', '*'],
102+
['efbbbf202a', ' *'],
103+
['fffe', ''],
104+
['fffe2a20', '\u202A'],
105+
['fffe2a', '\uFFFD'],
106+
['fffe00d72a', '\uD700\uFFFD'],
107+
['fffe00d82a', '\uFFFD\uFFFD'],
108+
['feff', ''],
109+
['feff202a', '\u202A'],
110+
['feff20', '\uFFFD'],
111+
['feffd70020', '\uD700\uFFFD'],
112+
['feffd80820', '\uFFFD\uFFFD'],
113+
],
114+
}
115+
116+
for (const [encoding, data] of Object.entries(fixtures)) {
117+
test(encoding, (t) => {
118+
for (const [hex, string] of data) {
119+
t.assert.strictEqual(legacyHookDecode(fromHex(hex), encoding), string, `${hex}`)
120+
}
121+
})
122+
}
123+
})
124+
86125
test('getBOMEncoding', (t) => {
87126
const fixtures = [
88127
[null, ''],

0 commit comments

Comments
 (0)