-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix integer overflow in ChunkingPlugin #8112
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah 32bit systems?
Codecov Report
@@ Coverage Diff @@
## master #8112 +/- ##
============================================
+ Coverage 51.88% 51.88% +<.01%
Complexity 25352 25352
============================================
Files 1606 1606
Lines 95069 95069
Branches 1378 1378
============================================
+ Hits 49326 49328 +2
+ Misses 45743 45741 -2
|
Exactly - some raspberry Pis and stuff like that. |
@MorrisJobke For me it does fix it. |
@MorrisJobke |
@MorrisJobke |
@pasxalisk Raspberry Pi 3 use a 64 bit ARM CPU ( https://en.wikipedia.org/wiki/ARM_Cortex-A53 ) can you check on another ARM CPU please? |
@voxdemonix true. It does use a x64 but the raspbian OS is 32bits. |
@@ -99,7 +99,7 @@ private function verifySize() { | |||
return; | |||
} | |||
$actualSize = $this->sourceNode->getSize(); | |||
if ((int)$expectedSize !== $actualSize) { | |||
if ((float)$expectedSize !== (float)$actualSize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually might create some very very tricky corner cases, where two not equal numbers get casted to the same float value, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an example? Currently this is exactly the case that one number is the float (because it can store higher numbers) and the other one is casted to integer and caused an overflow there and thus is not the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a small test program and with higher numbers there a ton of collisions. And it must be: Int has 31 bits for the actual number and a float only 23. See my other comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why you have to cast the values? String comparison not good enough?
If not, maybe bcmath/gmp should be used on 32bit systems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@icewind1991 @rullzer @nickvergessen What do you think about the cast to string? Is this the better approach?
Test program in c#:
Result:
|
@go2sh I don't know what The PHP documentation seems to imply that |
On the other hand, this seems more like an extra safety check (a file size match won't actually guarantee that the data was received correctly. Worst case, an error won't be reported when it should, but this won't prevent uploads from succeeding. |
This very tricky... I have no proper solution. |
Thank you for the patch @MorrisJobke , it does "solve" my problem. For those interested, PHP only has INTs and FLOATs defined, but whether they are 32-bit or 64-bit depends on the platform. The default behavior in PHP is to (quietly) convert INTs to FLOATs if they exceed PHP_INT_MAX. It seems like there is a proposal to introduce BIGINTs to PHP (https://wiki.php.net/rfc/bigint), but not implemented yet. The main problem with both approaches (casting to floats or ints) is that we lose precision. Floats would miss "small" errors, where the chunk size difference is beyond the precision, while ints fail in 32-bit int implementations, which the overflow would allow "large" chunk size errors to pass. Maybe a better approach would be to compare both (and casting ints, so we are only comparing the LSBs)? (Or to convert both to string, although I don't know to prevent overflow errors from happening before that) |
By the way, wouldn't it be better to checksum the files instead? This might require some changes in the client, but would give us a better check altogether than just chunk sizes and avoid the 32/64 bit debacle. |
This doesn't affect me, and I don't know the full context, but I'm thinking that:
|
What OS are you running in the rpi3? I'm using hypriotOS (debian based) and cannot pass over 2GB. I've patched the code. Thx |
Avoids errors when the size exceeds MAX_INT because of the cast to int. Better cast it to float to avoid this. Signed-off-by: Morris Jobke <hey@morrisjobke.de>
3d670a0
to
fc4e050
Compare
I updated this to be a cast to string. @pasxalisk @davidpoza @nariox Could you try the new patch and check if this works properly for you? |
@maanloper and @Danny3 reported that this already works in #7948 (comment) |
I'm now having a different issue, but not sure if it is part of this (seems to be). 2147483647 is 2³¹-1 The particular exception is being thrown by Since other people don't seem to having this problem, my guess is that I might want to file a new bug. But let me know what happens to you guys. |
Let's get this in |
backport to stable13 is in #8752 |
Avoids errors when the size exceeds MAX_INT because of the cast to int. Better cast it to float to avoid this.
Fix #7948 and #8109 (comment)
@nariox @pasxalisk Could you check if this fixes the issue for you?