avoid signed overflow in cache memory limit#4561
Conversation
|
Thanks for the PR. Whilst we're fixing this, I think we might also want to use |
76a3289 to
69a016f
Compare
|
Makes sense. Switched all three cache values to Also added a guard in |
|
Thanks for the updates, it looks like we might have to skip the max memory test on 32-bit systems. The |
Read the cache values as unsigned integers and keep the megabyte to byte conversion in size_t, so the memory limit no longer wraps at 2048MB and above. Reject non-integer and negative values in the JavaScript layer.
69a016f to
6b3e1c7
Compare
|
Good shout. The 4096MB byte count overflows a 32-bit |
|
Thank you. (The wasm32 test failure is unrelated, I'm fixing this now.) |
sharp.cache({ memory }) passes the megabyte value through to the native cache helper, which reads it as a 32-bit int and multiplies by 1048576 to convert to bytes before handing the result to vips_cache_set_max_mem. The multiply runs in 32-bit signed arithmetic and only widens to the size_t the function expects afterwards, so any value of 2048 or above overflows first. A 2048MB request wraps to a negative number that sign-extends to roughly 16 exabytes, which leaves the operation cache effectively unbounded, while exactly 4096MB wraps to zero and silently disables it. I came across this while confirming that larger cache limits were honoured and saw the reported memory.max had no relation to the value passed in. Casting the operand to size_t before the multiply keeps the conversion in 64-bit so the byte count stays correct across the documented range. I have limited the change to that one expression and added a regression test at 4096MB, which reported a maximum of zero beforehand.