| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3e50a2f commit 6f9e084
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,7 @@ const { | |||
| 24 | 24 | getRawPointer, | |
| 25 | 25 | kFastArguments, | |
| 26 | 26 | kFastBufferInvoke, | |
| 27 | + uintptrMax, | ||
| 27 | 28 | } = internalBinding('ffi'); | |
| 28 | 29 | ||
| 29 | 30 | const { | |
@@ -110,6 +111,14 @@ function needsPointerConversion(type) { | |||
| 110 | 111 | needsNullPointerConversion(type) || needsStringPointerConversion(type); | |
| 111 | 112 | } | |
| 112 | 113 | ||
| 114 | + function validateFastPointerArg(type, value, index) { | ||
| 115 | + if (needsPointerConversion(type) && typeof value === 'bigint' && | ||
| 116 | + (value < 0n || value > uintptrMax)) { | ||
| 117 | + throwFFIArgError( | ||
| 118 | + `Argument ${index} must be a non-negative pointer bigint`); | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 113 | 122 | function hasStringPointerArg(type, value) { | |
| 114 | 123 | return typeof value === 'string' && needsStringPointerConversion(type); | |
| 115 | 124 | } | |
@@ -159,6 +168,7 @@ function getStringConversionPointer(state, value, index) { | |||
| 159 | 168 | } | |
| 160 | 169 | ||
| 161 | 170 | function convertPointerArg(type, value, stringState, index) { | |
| 171 | + validateFastPointerArg(type, value, index); | ||
| 162 | 172 | if (needsNullPointerConversion(type) && | |
| 163 | 173 | (value === null || value === undefined)) { | |
| 164 | 174 | return 0n; | |
@@ -261,6 +271,7 @@ function wrapWithRawPointerConversions(rawFn, argumentTypes, owner) { | |||
| 261 | 271 | throwFFIArgCountError(1, arguments.length); | |
| 262 | 272 | } | |
| 263 | 273 | validateFastIntegerArg(t0, a0, 0); | |
| 274 | + validateFastPointerArg(t0, a0, 0); | ||
| 264 | 275 | let arg = a0; | |
| 265 | 276 | if (needsNullPointerConversion(t0) && | |
| 266 | 277 | (arg === null || arg === undefined)) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1341,9 +1341,9 @@ static void Initialize(Local<Object> target, | |||
| 1341 | 1341 | Boolean::New(isolate, CHAR_MIN < 0)) | |
| 1342 | 1342 | .Check(); | |
| 1343 | 1343 | ||
| 1344 | - // The shared-buffer fast path uses `uintptrMax` to reject pointer BigInts | ||
| 1345 | - // that would otherwise be silently truncated by `ReadFFIArgFromBuffer`'s | ||
| 1346 | - // `memcpy(..., type->size, ...)` on 32-bit platforms. The slow path | ||
| 1344 | + // The JavaScript fast paths use `uintptrMax` to reject pointer BigInts that | ||
| 1345 | + // would otherwise be silently truncated by V8 or, on 32-bit platforms, by | ||
| 1346 | + // `ReadFFIArgFromBuffer`'s `memcpy(..., type->size, ...)`. The slow path | ||
| 1347 | 1347 | // rejects the same values through `ToFFIArgument`. | |
| 1348 | 1348 | target | |
| 1349 | 1349 | ->Set(context, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -68,3 +68,34 @@ test('fast FFI validates integer argument ranges', () => { | |||
| 68 | 68 | lib.close(); | |
| 69 | 69 | } | |
| 70 | 70 | }); | |
| 71 | + | ||
| 72 | + test('fast FFI validates pointer BigInt ranges', () => { | ||
| 73 | + const lib = new ffi.DynamicLibrary(libraryPath); | ||
| 74 | + try { | ||
| 75 | + for (const type of ['pointer', 'ptr', 'string', 'str', | ||
| 76 | + 'buffer', 'arraybuffer']) { | ||
| 77 | + const identityPointer = lib.getFunction('identity_pointer', { | ||
| 78 | + arguments: [type], | ||
| 79 | + return: 'pointer', | ||
| 80 | + }); | ||
| 81 | + const sumBuffer = lib.getFunction('sum_buffer', { | ||
| 82 | + arguments: [type, 'u64'], | ||
| 83 | + return: 'u64', | ||
| 84 | + }); | ||
| 85 | + function callSingle(value) { return identityPointer(value); } | ||
| 86 | + | ||
| 87 | + function callMultiple(value) { return sumBuffer(value, 0n); } | ||
| 88 | + | ||
| 89 | + optimize(callSingle, 0n); | ||
| 90 | + optimize(callMultiple, 0n); | ||
| 91 | + | ||
| 92 | + const expect = { code: 'ERR_INVALID_ARG_VALUE' }; | ||
| 93 | + for (const call of [callSingle, callMultiple]) { | ||
| 94 | + assert.throws(() => call(-1n), expect); | ||
| 95 | + assert.throws(() => call((2n ** 64n) + 5n), expect); | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + } finally { | ||
| 99 | + lib.close(); | ||
| 100 | + } | ||
| 101 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments