gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lost information converting decoded value to in32_t


From: Riccardo Mottola
Subject: Re: Lost information converting decoded value to in32_t
Date: Mon, 25 May 2020 21:57:02 +0000
User-agent: GNUMail (Version (null))

Hi,

after hacking an evening with this with Fred, I have an update.

I hope Richard, Wolfgang, David... can chime in.

I opened a PR with a proposed solution which "works"

On 2020-05-25 07:50:26 +0000 Fred Kiefer <address@hidden> wrote:


Looks like your archive has a value that gets encodes as an NSInteger and this is 32 bit on your current machine but the original encoded value was actually 64 bit and uses more than the 32 bit you are able to read. The best thing to do is to find out which value it is that causes the behaviour and encode (and decode) it as a long.

And to answer your question, the message itself is surely not a bug, it just shows how clever base tries to deal with different encoded values. The actual encoding may be a bug. There it would really help to know where it is coming from.

The issue is in NSUnarchiver itself, around line 1401.
The unarchived NSInteger coming from the gorm file is just "2":

However the tests fail, even with simulations:
(gdb) p big
$1 = 2
(gdb) p big > 2147483647
$2 = 0
(gdb) p big < -2147483648
$3 = 1

What is interesting, if gdb follows the same literal rules and promotions of GCC:

(gdb) p  (int64_t)-2147483648
$8 = 2147483648
(gdb) p  (int64_t)-2147483648l
$9 = 2147483648
(gdb) p  (int64_t)-2147483648L
$10 = 2147483648

(gdb) p  (int64_t)-2147483647
$15 = -2147483647

Whatever I do as a literal suffix, it comes out positive. One value less and it works.
Here I am at loss with types and constants.

Looking up on the internet, I found the explanation is that the literal is only the number part without signed, regarless if it is a signed or unsigned decimal. Then the - operator is performed. For this reason it is usually written as (-2147483647 -1) in the limits header files. With that explanation, it is promoted to the "unsinged" type and then the "-" operation fails and underflows.

For that reason I propose to change the lower bounds check to an equivalent easy to read
            if (big > 2147483647 || big + 2147483648 < 0

instead of the "minus 1" trick.


I wanted to open a PR on an "fix_32bit_decode" branch, but apparently... everything got pushed to master without the branch. Sorry.

So please if you disagree, revert and fix with the style you prefer. Also, perhaps, technically, we should apply the same style for int8-t and int16_t although we perhaps will never encounter that because minimum literal type is "int".

Riccardo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]