Skip to content
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

Restore non-havePack64 logic for negative integers #30

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

trwyant
Copy link
Contributor

@trwyant trwyant commented Jan 21, 2025

This was dropped in the refactor of 1.505. I guess Perls without 64-bit integers are rare these days; I only encountered it on a Raspberry Pi.

This was dropped in the refactor of 1.505. I guess Perls without 64-bit
integers are rare these days; I only encountered it on a Raspberry Pi.
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@trwyant trwyant temporarily deployed to automated_testing January 21, 2025 16:29 — with GitHub Actions Inactive
@coveralls
Copy link

coveralls commented Jan 21, 2025

Coverage Status

coverage: 87.545% (+0.09%) from 87.455%
when pulling 4d33f1a on trwyant:trw_restore_non_havePack64_negative_numbers
into d169b9c on briandfoy:master.

@coveralls
Copy link

Coverage Status

coverage: 87.091% (-0.4%) from 87.455%
when pulling c27baff on trwyant:trw_restore_non_havePack64_negative_numbers
into d169b9c on briandfoy:master.

3 similar comments
@coveralls
Copy link

Coverage Status

coverage: 87.091% (-0.4%) from 87.455%
when pulling c27baff on trwyant:trw_restore_non_havePack64_negative_numbers
into d169b9c on briandfoy:master.

@coveralls
Copy link

Coverage Status

coverage: 87.091% (-0.4%) from 87.455%
when pulling c27baff on trwyant:trw_restore_non_havePack64_negative_numbers
into d169b9c on briandfoy:master.

@coveralls
Copy link

Coverage Status

coverage: 87.091% (-0.4%) from 87.455%
when pulling c27baff on trwyant:trw_restore_non_havePack64_negative_numbers
into d169b9c on briandfoy:master.

@briandfoy
Copy link
Owner

Can you verify that the macOS plists tools can handle these numbers? As I recall, we had to drop some of this stuff because we were generating plist files that would cause problems. I noted in the Changes that these numbers had to be longs.

Along with this, could you add some tests to write and read the data to verify they round trip?

@briandfoy briandfoy added Type: feature request add a feature that does not exist Status: needs testing the fix needs to be tested Status: changes requested adjust the pull request as noted in comments labels Jan 21, 2025
@trwyant
Copy link
Contributor Author

trwyant commented Jan 24, 2025

Acknowledged, and thanks for both the module and the feedback. Will do. Maybe over the weekend (and the check is in the mail ...)

@trwyant
Copy link
Contributor Author

trwyant commented Jan 31, 2025

I gave it the old college try. The tests have been expanded to include pretty much the whole range of 64-bit integers, both positive and negative, with the ones over 32 bits represented as Math::BigInt objects independently of Perl integer size.

The implementation of negative integers basically computes the 64-bit 2s complement and then treats the result as a 54-bit non-negative integer. Non-negative integers are handled by extracting $low and $high using bmod() and brsft() respectively, and then doing pack( 'CNN', tagInteger + 3, $high->numify, $low->numify).

I have not yet done a full round-trip test, though I am willing to do so. As I understand it, this would start with a hand-rolled xml1 property list containing appropriate integer values, use Mac::PropertyList::WriteBinary to write a binary1 file, read that back with Mac::PropertyList::ReadBinary, and ensure we got the same XML.

@trwyant
Copy link
Contributor Author

trwyant commented Jan 31, 2025

Looks like some of the earlier versions of Perl have problems. I will look into this.

@trwyant
Copy link
Contributor Author

trwyant commented Jan 31, 2025

I don't know what to make of the coverage test failures. I do duplicate the Perl 5.12 module test failure, though. I will investigate further, but one possible solution is a version bump on the Math::BigInt requirement. It is currently 0.

@briandfoy
Copy link
Owner

It looks like v5.10 and v5.12 need a better Math::BigInt. No idea why.

I made a few changes in the workflows branch that you can merge. Or cherry-pick the commits that you want.

Don't worry about coverage right now. Once it's working we can figure out that bit.

@trwyant
Copy link
Contributor Author

trwyant commented Feb 2, 2025

The failing test in t/write_binary.t is the largest signed integer representable in 64 bits. After a lot of undirected thrashing around, I realized that under a 64-bit Perl 5.12 (Math::BigInt 1.89_01) Math::BigInt->numify() was upgrading that number to a float. Under a 64-nit Perl 5.14 (Math::BigInt 1.994) the numify() method returns an integer.

Unfortunately the Math-BigInt GitHub reposirory has no tags for either of these versions and neither does Meta::CPAN. An attempt to upgrade my 64-bit Perl 5.12 to 1.993 using the Meta::CPAN tarball and cpan> install . resulted in a slew of errors and the current Math::BigInt being installed.

My tests also include the smallest signed 64-bit integer, and that test passed, but I have not investigated whether the numify() method upgrades that also and we just got lucky. I'm sure similar things could happen in a 32-bit Perl 5.12, but I do not have one on hand.

Interestingly, the code of the Math::BigInt->numify() method did not change between 1.89_01 (Perl 5.12) and 1.994 (Perl 5.14). At least, not in the strictly lexical sense. But the heavy lifting is done by a call to $CALC->_num(). This turns out to be a static method, but it is on Math::BigInt::FastCalc under 1.89_01, but Math::BigInt::Calc under 1.994. But I have dug no deeper so far.

At this point it looks like the critical dependency is an indirect one from Mac::PropertyList's point of view. At this point in its life Math-BigInt uses the Module::Install toolchain (which I am not very conversant with), though it has since been converted to ExtUtils::MakeMaker.

An alternate implementation that might (or might not) sidestep this whole mess is to implement Mac::PropertyList::WriteBinary in terms of Math::BigInt->to_hex() (suitably padded) and pack 'CH*', ... instead of Math::BigInt->numify(). The problem (or at least inconvenience) here is that for the to_hex() implementation to work we have to know we have a Math::BigInt object. The numify() implementation does not require this knowledge, because Math::BigIntoverloads numification to numify(), meaning we do not need to worry about whether we have a Math::BigInt object or a scalar.

Right now I have no conclusion to any of this. I'm just letting you know where I am at the moment.

@briandfoy
Copy link
Owner

If the current Math::BigInt works, and it appears so, I wouldn't worry too much about the why.

@briandfoy
Copy link
Owner

I looked in Apple code in CFBinaryPList.c. It seems to support integers of arbitrary precision, and it specifically mentions 64-bit. So, that answers this question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: changes requested adjust the pull request as noted in comments Status: needs testing the fix needs to be tested Status: needs verification issue needs to be verified Type: feature request add a feature that does not exist
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants