ckruse / CFPropertyList

Read, write and manipulate both binary and XML property lists as defined by apple
MIT License
212 stars 47 forks source link

fix to enable reading/writing of unsigned 64-bit integers in binary plists #51

Closed nguyen-phillip closed 6 years ago

nguyen-phillip commented 6 years ago

The binary plist format encodes unsigned 64 bit integers using 16 bytes, with the value stored in the lower 8 bytes. This fixes a bug in rbBinaryCFPropertyList that prevented it from decoding/encoding unsigned 64 bit integers.

ckruse commented 6 years ago

Thanks for your contribution!

Hm, test/test_integer.rb fails. Can you have a look? I guess the 8 byte plist file doesn't match any longer.

nguyen-phillip commented 6 years ago

Thanks for getting back to me so quickly! Sorry about the broken tests, I was being inefficient about encoding positive integers that could be interpreted as 8-byte signed ints. Updated to fix this, and added some new tests for unsigned 8 byte ints.

ckruse commented 6 years ago

Thanks again for your contribution!

I'm sorry, but there might be a bug in your plist file. When I open test/reference/int_8_bytes_unsigned.plist with the PList editor, it shows me not 232 but -9.223.372.036.854.775.808 - which is a number with the first 33 bytes set to 1 if I am correct? When I change the number to `232(4.294.967.296) the 8 byte tests fail (test_write_8_bytes_unsignedas well astest_read_8_bytes_unsigned`). So the example plist file seems to be wrong, doesn't it?

nguyen-phillip commented 6 years ago

The number in int_8_bytes_unsigned is 2**63 = 9223372036854775808 = 0x8000000000000000, which is the smallest positive number that can't be stored in an 8 byte signed int. I created int_8_bytes_unsigned.xml first as

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

9223372036854775808

Then used Apple's plutil command to convert the xml plist to binary via: plutil -convert binary1 int_8_bytes_unsigned.xml -o int_8_bytes_unsigned.plist

Running "plutil -p int_8_bytes_unsigned.plist" prints out 9223372036854775808 as expected.

It's strange that the Xcode plist editor shows it as a negative number. My guess is that it is casting it to a signed int64_t after reading it out.

For some context, the impetus for all this was that the value 0x8000000000000007 was showing up as an integer value in the binary plist com.apple.ncprefs.plist, the specific value apparently being written out by Apple's Notes.app.

ckruse commented 6 years ago

Ah, hm, that's interesting. You are right, plutil -p shows the right value. Hm. I guess it's a display bug in Xcode plist editor, then. Gonna merge it and make a new release, thanks a lot!

ckruse commented 6 years ago

✅ done - just pushed 2.3.6 to rubygems