Skip to content

Commit 73e75c1

Browse files
committed
Align string/buffer conversion behaviors to Node.js
1 parent ab72389 commit 73e75c1

2 files changed

Lines changed: 48 additions & 18 deletions

File tree

example/src/tests/utils/encoding_tests.ts

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,44 @@ test(SUITE, 'hex decode is case-insensitive', () => {
4545
expect(lower).to.deep.equal(upper);
4646
});
4747

48-
test(SUITE, 'hex decode rejects odd-length string', () => {
49-
expect(() => stringToBuffer('abc', 'hex')).to.throw();
48+
test(SUITE, '[Node.js] Test single hex character is discarded.', () => {
49+
expect(toU8(stringToBuffer('A', 'hex'))).to.deep.equal(new Uint8Array([]));
5050
});
5151

52-
test(SUITE, 'hex decode rejects invalid characters', () => {
53-
expect(() => stringToBuffer('zzzz', 'hex')).to.throw();
52+
test(
53+
SUITE,
54+
'[Node.js] Test that if a trailing character is discarded, rest of string is processed.',
55+
() => {
56+
expect(toU8(stringToBuffer('Abx', 'hex'))).to.deep.equal(
57+
new Uint8Array([0xab]),
58+
);
59+
expect(toU8(stringToBuffer('abc', 'hex'))).to.deep.equal(
60+
new Uint8Array([0xab]),
61+
);
62+
},
63+
);
64+
65+
test(SUITE, '[Node.js] Test hex strings and bad hex strings', () => {
66+
expect(toU8(stringToBuffer('abcdxx', 'hex'))).to.deep.equal(
67+
new Uint8Array([0xab, 0xcd]),
68+
);
69+
expect(toU8(stringToBuffer('xxabcd', 'hex'))).to.deep.equal(
70+
new Uint8Array([]),
71+
);
72+
expect(toU8(stringToBuffer('cdxxab', 'hex'))).to.deep.equal(
73+
new Uint8Array([0xcd]),
74+
);
75+
76+
const bytes = new Uint8Array(256);
77+
for (let i = 0; i < 256; i++) {
78+
bytes[i] = i;
79+
}
80+
81+
const hex = bufferToString(bytes.buffer as ArrayBuffer, 'hex');
82+
const badHex = `${hex.slice(0, 256)}xx${hex.slice(256, 510)}`;
83+
expect(toU8(stringToBuffer(badHex, 'hex'))).to.deep.equal(
84+
bytes.slice(0, 128),
85+
);
5486
});
5587

5688
// --- Base64 ---
@@ -658,18 +690,22 @@ test(SUITE, 'ascii encode strips high bit', () => {
658690
expect(str.charCodeAt(1)).to.equal(0x48); // 0xC8 & 0x7F = 0x48
659691
});
660692

661-
test(SUITE, 'ascii decode strips high bit', () => {
662-
const str = String.fromCharCode(0xc8); // above 0x7F
663-
const ab = stringToBuffer(str, 'ascii');
664-
expect(toU8(ab)[0]).to.equal(0x48); // 0xC8 & 0x7F = 0x48
665-
});
666-
667693
test(SUITE, 'ascii roundtrip printable ASCII', () => {
668694
const str = 'Hello, World! 123';
669695
const ab = stringToBuffer(str, 'ascii');
670696
expect(bufferToString(ab, 'ascii')).to.equal(str);
671697
});
672698

699+
test(
700+
SUITE,
701+
'[Node.js] Test for proper ascii Encoding, length should be 4',
702+
() => {
703+
expect(toU8(stringToBuffer('\u00fcber', 'ascii'))).to.deep.equal(
704+
new Uint8Array([252, 98, 101, 114]),
705+
);
706+
},
707+
);
708+
673709
test(
674710
SUITE,
675711
"[Node.js] ASCII conversion in node.js simply masks off the high bits, it doesn't do transliteration.",

packages/react-native-quick-crypto/cpp/utils/HybridUtils.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,13 @@ namespace {
3535
}
3636

3737
std::vector<uint8_t> decodeHex(const std::string& hex) {
38-
if (hex.length() % 2 != 0) {
39-
throw std::runtime_error("Invalid hex string length");
40-
}
4138
std::vector<uint8_t> result;
4239
result.reserve(hex.length() / 2);
43-
for (size_t i = 0; i < hex.length(); i += 2) {
40+
for (size_t i = 0; i + 1 < hex.length(); i += 2) {
4441
int hi = hexCharToVal(hex[i]);
4542
int lo = hexCharToVal(hex[i + 1]);
4643
if (hi < 0 || lo < 0) {
47-
throw std::runtime_error("Invalid hex character");
44+
break;
4845
}
4946
result.push_back(static_cast<uint8_t>((hi << 4) | lo));
5047
}
@@ -192,9 +189,6 @@ std::shared_ptr<ArrayBuffer> HybridUtils::stringToBuffer(const std::string& str,
192189
}
193190
if (encoding == "ascii") {
194191
auto decoded = decodeLatin1(str);
195-
for (auto& b : decoded) {
196-
b &= 0x7F;
197-
}
198192
return ArrayBuffer::move(std::move(decoded));
199193
}
200194
throw std::runtime_error("Unsupported encoding: " + encoding);

0 commit comments

Comments
 (0)