const strLen = string.length
- if (length > strLen / 2) {
- length = strLen / 2
+ if (length > (strLen >>> 1)) {
+ length = strLen >>> 1
}
- let i
- for (i = 0; i < length; ++i) {
- const a = hexCharValueTable[string[i * 2]]
- const b = hexCharValueTable[string[i * 2 + 1]]
- if (a === undefined || b === undefined) {
+
+ for (let i = 0; i < length; ++i) {
+ const a = string.charCodeAt(i * 2 + 0)
+ const b = string.charCodeAt(i * 2 + 1)
+ const hi = hexCharValueTable[a & 0x7f]
+ const lo = hexCharValueTable[b & 0x7f]
+
+ if ((a | b | hi | lo) & ~0x7f) {
return i
}
- buf[offset + i] = a << 4 | b
+
+ buf[offset + i] = (hi << 4) | lo
}
- return i
+
+ return length
}
function utf8Write (buf, string, offset, length) {
})()
// hex lookup table for Buffer.from(x, 'hex')
-const hexCharValueTable = {
- 0: 0,
- 1: 1,
- 2: 2,
- 3: 3,
- 4: 4,
- 5: 5,
- 6: 6,
- 7: 7,
- 8: 8,
- 9: 9,
- a: 10,
- b: 11,
- c: 12,
- d: 13,
- e: 14,
- f: 15,
- A: 10,
- B: 11,
- C: 12,
- D: 13,
- E: 14,
- F: 15
-}
+/* eslint-disable no-multi-spaces, indent */
+const hexCharValueTable = [
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1
+]
+/* eslint-enable no-multi-spaces, indent */
// Return not function with Error if BigInt not supported
function defineBigIntMethod (fn) {
--- /dev/null
+'use strict'
+
+const Buffer = require('../').Buffer
+const test = require('tape')
+
+test('buffer.write("hex") should stop on invalid characters', function (t) {
+ // Test the entire 16-bit space.
+ for (let ch = 0; ch <= 0xffff; ch++) {
+ // 0-9
+ if (ch >= 0x30 && ch <= 0x39) {
+ continue
+ }
+
+ // A-F
+ if (ch >= 0x41 && ch <= 0x46) {
+ continue
+ }
+
+ // a-f
+ if (ch >= 0x61 && ch <= 0x66) {
+ continue
+ }
+
+ for (const str of [
+ 'abcd' + String.fromCharCode(ch) + 'ef0',
+ 'abcde' + String.fromCharCode(ch) + 'f0',
+ 'abcd' + String.fromCharCode(ch + 0) + String.fromCharCode(ch + 1) + 'f0',
+ 'abcde' + String.fromCharCode(ch + 0) + String.fromCharCode(ch + 1) + '0'
+ ]) {
+ const buf = Buffer.alloc(4)
+ t.equal(str.length, 8)
+ t.equal(buf.write(str, 'hex'), 2)
+ t.equal(buf.toString('hex'), 'abcd0000')
+ t.equal(Buffer.from(str, 'hex').toString('hex'), 'abcd')
+ }
+ }
+
+ t.end()
+})
+
+test('buffer.write("hex") should truncate odd string lengths', function (t) {
+ const buf = Buffer.alloc(32)
+ const charset = '0123456789abcdef'
+
+ let str = ''
+
+ for (let i = 0; i < 63; i++) {
+ str += charset[Math.random() * charset.length | 0]
+ }
+
+ t.equal(buf.write('abcde', 'hex'), 2)
+ t.equal(buf.toString('hex', 0, 3), 'abcd00')
+
+ buf.fill(0)
+
+ t.equal(buf.write(str, 'hex'), 31)
+ t.equal(buf.toString('hex', 0, 32), str.slice(0, -1) + '00')
+ t.end()
+})