| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3801790 commit c33933e
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -159,7 +159,8 @@ void CallbackInfo::WeakCallback(Isolate* isolate) { | |||
| 159 | 159 | // Parse index for external array data. | |
| 160 | 160 | inline MUST_USE_RESULT bool ParseArrayIndex(Local<Value> arg, | |
| 161 | 161 | size_t def, | |
| 162 | - size_t* ret) { | ||
| 162 | + size_t* ret, | ||
| 163 | + size_t needed = 0) { | ||
| 163 | 164 | if (arg->IsUndefined()) { | |
| 164 | 165 | *ret = def; | |
| 165 | 166 | return true; | |
@@ -173,7 +174,7 @@ inline MUST_USE_RESULT bool ParseArrayIndex(Local<Value> arg, | |||
| 173 | 174 | // Check that the result fits in a size_t. | |
| 174 | 175 | const uint64_t kSizeMax = static_cast<uint64_t>(static_cast<size_t>(-1)); | |
| 175 | 176 | // coverity[pointless_expression] | |
| 176 | - if (static_cast<uint64_t>(tmp_i) > kSizeMax) | ||
| 177 | + if (static_cast<uint64_t>(tmp_i) > kSizeMax - needed) | ||
| 177 | 178 | return false; | |
| 178 | 179 | ||
| 179 | 180 | *ret = static_cast<size_t>(tmp_i); | |
@@ -805,17 +806,28 @@ void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) { | |||
| 805 | 806 | CHECK_NE(ts_obj_data, nullptr); | |
| 806 | 807 | ||
| 807 | 808 | T val = args[1]->NumberValue(env->context()).FromMaybe(0); | |
| 808 | - size_t offset = args[2]->IntegerValue(env->context()).FromMaybe(0); | ||
| 809 | 809 | ||
| 810 | 810 | size_t memcpy_num = sizeof(T); | |
| 811 | + size_t offset; | ||
| 811 | 812 | ||
| 812 | - if (should_assert) { | ||
| 813 | - THROW_AND_RETURN_IF_OOB(offset + memcpy_num >= memcpy_num); | ||
| 814 | - THROW_AND_RETURN_IF_OOB(offset + memcpy_num <= ts_obj_length); | ||
| 813 | + // If the offset is negative or larger than the size of the ArrayBuffer, | ||
| 814 | + // throw an error (if needed) and return directly. | ||
| 815 | + if (!ParseArrayIndex(args[2], 0, &offset, memcpy_num) || | ||
| 816 | + offset >= ts_obj_length) { | ||
| 817 | + if (should_assert) | ||
| 818 | + THROW_AND_RETURN_IF_OOB(false); | ||
| 819 | + return; | ||
| 815 | 820 | } | |
| 816 | 821 | ||
| 817 | - if (offset + memcpy_num > ts_obj_length) | ||
| 818 | - memcpy_num = ts_obj_length - offset; | ||
| 822 | + // If the offset is too large for the entire value, but small enough to fit | ||
| 823 | + // part of the value, throw an error and return only if should_assert is | ||
| 824 | + // true. Otherwise, write the part of the value that fits. | ||
| 825 | + if (offset + memcpy_num > ts_obj_length) { | ||
| 826 | + if (should_assert) | ||
| 827 | + THROW_AND_RETURN_IF_OOB(false); | ||
| 828 | + else | ||
| 829 | + memcpy_num = ts_obj_length - offset; | ||
| 830 | + } | ||
| 819 | 831 | ||
| 820 | 832 | union NoAlias { | |
| 821 | 833 | T val; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,28 +4,33 @@ const assert = require('assert'); | |||
| 4 | 4 | ||
| 5 | 5 | // testing buffer write functions | |
| 6 | 6 | ||
| 7 | + const outOfRange = /^RangeError: (?:Index )?out of range(?: index)?$/; | ||
| 8 | + | ||
| 7 | 9 | function write(funx, args, result, res) { | |
| 8 | 10 | { | |
| 9 | 11 | const buf = Buffer.alloc(9); | |
| 10 | 12 | assert.strictEqual(buf[funx](...args), result); | |
| 11 | 13 | assert.deepStrictEqual(buf, res); | |
| 12 | 14 | } | |
| 13 | 15 | ||
| 14 | - { | ||
| 15 | - const invalidArgs = Array.from(args); | ||
| 16 | - invalidArgs[1] = -1; | ||
| 17 | - assert.throws( | ||
| 18 | - () => Buffer.alloc(9)[funx](...invalidArgs), | ||
| 19 | - /^RangeError: (?:Index )?out of range(?: index)?$/ | ||
| 20 | - ); | ||
| 21 | - } | ||
| 16 | + writeInvalidOffset(-1); | ||
| 17 | + writeInvalidOffset(9); | ||
| 22 | 18 | ||
| 23 | 19 | { | |
| 24 | 20 | const buf2 = Buffer.alloc(9); | |
| 25 | 21 | assert.strictEqual(buf2[funx](...args, true), result); | |
| 26 | 22 | assert.deepStrictEqual(buf2, res); | |
| 27 | 23 | } | |
| 28 | 24 | ||
| 25 | + function writeInvalidOffset(offset) { | ||
| 26 | + const newArgs = Array.from(args); | ||
| 27 | + newArgs[1] = offset; | ||
| 28 | + assert.throws(() => Buffer.alloc(9)[funx](...newArgs), outOfRange); | ||
| 29 | + | ||
| 30 | + const buf = Buffer.alloc(9); | ||
| 31 | + buf[funx](...newArgs, true); | ||
| 32 | + assert.deepStrictEqual(buf, Buffer.alloc(9)); | ||
| 33 | + } | ||
| 29 | 34 | } | |
| 30 | 35 | ||
| 31 | 36 | write('writeInt8', [1, 0], 1, Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0])); | |
@@ -46,3 +51,45 @@ write('writeDoubleBE', [1, 1], 9, Buffer.from([0, 63, 240, 0, 0, 0, 0, 0, 0])); | |||
| 46 | 51 | write('writeDoubleLE', [1, 1], 9, Buffer.from([0, 0, 0, 0, 0, 0, 0, 240, 63])); | |
| 47 | 52 | write('writeFloatBE', [1, 1], 5, Buffer.from([0, 63, 128, 0, 0, 0, 0, 0, 0])); | |
| 48 | 53 | write('writeFloatLE', [1, 1], 5, Buffer.from([0, 0, 0, 128, 63, 0, 0, 0, 0])); | |
| 54 | + | ||
| 55 | + function writePartial(funx, args, result, res) { | ||
| 56 | + assert.throws(() => Buffer.alloc(9)[funx](...args), outOfRange); | ||
| 57 | + const buf = Buffer.alloc(9); | ||
| 58 | + assert.strictEqual(buf[funx](...args, true), result); | ||
| 59 | + assert.deepStrictEqual(buf, res); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + // Test partial writes (cases where the buffer isn't large enough to hold the | ||
| 63 | + // entire value, but is large enough to hold parts of it). | ||
| 64 | + writePartial('writeIntBE', [0x0eadbeef, 6, 4], 10, | ||
| 65 | + Buffer.from([0, 0, 0, 0, 0, 0, 0x0e, 0xad, 0xbe])); | ||
| 66 | + writePartial('writeIntLE', [0x0eadbeef, 6, 4], 10, | ||
| 67 | + Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); | ||
| 68 | + writePartial('writeInt16BE', [0x1234, 8], 10, | ||
| 69 | + Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x12])); | ||
| 70 | + writePartial('writeInt16LE', [0x1234, 8], 10, | ||
| 71 | + Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x34])); | ||
| 72 | + writePartial('writeInt32BE', [0x0eadbeef, 6], 10, | ||
| 73 | + Buffer.from([0, 0, 0, 0, 0, 0, 0x0e, 0xad, 0xbe])); | ||
| 74 | + writePartial('writeInt32LE', [0x0eadbeef, 6], 10, | ||
| 75 | + Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); | ||
| 76 | + writePartial('writeUIntBE', [0xdeadbeef, 6, 4], 10, | ||
| 77 | + Buffer.from([0, 0, 0, 0, 0, 0, 0xde, 0xad, 0xbe])); | ||
| 78 | + writePartial('writeUIntLE', [0xdeadbeef, 6, 4], 10, | ||
| 79 | + Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); | ||
| 80 | + writePartial('writeUInt16BE', [0x1234, 8], 10, | ||
| 81 | + Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x12])); | ||
| 82 | + writePartial('writeUInt16LE', [0x1234, 8], 10, | ||
| 83 | + Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0x34])); | ||
| 84 | + writePartial('writeUInt32BE', [0xdeadbeef, 6], 10, | ||
| 85 | + Buffer.from([0, 0, 0, 0, 0, 0, 0xde, 0xad, 0xbe])); | ||
| 86 | + writePartial('writeUInt32LE', [0xdeadbeef, 6], 10, | ||
| 87 | + Buffer.from([0, 0, 0, 0, 0, 0, 0xef, 0xbe, 0xad])); | ||
| 88 | + writePartial('writeDoubleBE', [1, 2], 10, | ||
| 89 | + Buffer.from([0, 0, 63, 240, 0, 0, 0, 0, 0])); | ||
| 90 | + writePartial('writeDoubleLE', [1, 2], 10, | ||
| 91 | + Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 240])); | ||
| 92 | + writePartial('writeFloatBE', [1, 6], 10, | ||
| 93 | + Buffer.from([0, 0, 0, 0, 0, 0, 63, 128, 0])); | ||
| 94 | + writePartial('writeFloatLE', [1, 6], 10, | ||
| 95 | + Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 128])); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments