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

Fix bug with i32 encoding #542

Merged
merged 8 commits into from
May 24, 2022
Merged

Conversation

G1gg1L3s
Copy link
Contributor

@G1gg1L3s G1gg1L3s commented May 20, 2022

This PR fixes a bug with int32 encoding. Bug was triggered with negative int32 values, when we insert them and then select with text encoding.

There were two ways of fixing this bug:

Fix insertion (which is implemented here)

Acra normalizes integers into int64 text before encrypting and sending into the database. The normalization happens here.
For an int32 the whole process looked like:

[4 bytes] -> uint32 -> int64 -> text

But the issue is, expanding from uint32 into int64 happens signless. So, if the integer is -2061435539 the whole process would looks like:

[8520fd6d] -> uint32(2233531757) -> int64(2233531757) -> "2233531757"

This PR adds explicit conversion from uint32 into int32, so the compiler can omit correct instruction for expansions with a negative sign:

[8520fd6d] -> uint32(2233531757) -> int32(-2061435539) -> int64(-2061435539) -> "-2061435539"

But, this will not work with the values encrypted before this change, the bug can still remain in the database of some users

Fix selection

This is the fix I was first thinking of, and even implemented that, so if you believe this way should be used instead/with the previous one, it can be easily applied.

When we encode integer values in postgres, we create IntValue object, defined here. In consists of an int value and a string one. String is used as an optimization, because the whole int value is produced from string, so in case of text encoding, we can reuse that string.

But because strings are signless for int32 (see reasons above), this doesn't work. The way to correct is to explicitly calculate string representation based on an integer value.


I don't know which variant is better, so I'm here for your opinion.

Checklist

This also brings new dependency - psycopg v3. This is a lot better
version of psycopg2, with new supported features, like extended
and prepared queries. In our case, we are interested in additional
type parameters in a Parse packets, which psyco specifies by default.
This place is responsible for normalizing values into the one form
before encrypting and putting into database. Also, this is where
the problem is.
By default, acra converts all integers into int64, then serializes
it into a textual representation and then encrypts.

But transforming binary int32 into int64 looked like:

  bytes -> uint32 -> int64 -> text

Which is wrong, because if in case of negative int32, the sign was
dropped at uint32 and then it wasn't restored after converting into
int64.

Fix this by properly converting int32 directly to int64, so the
compiler can insert correct instruction that can handle negative
sign:

  bytes -> uint32 -> int32 -> int64 -> text
@G1gg1L3s G1gg1L3s mentioned this pull request May 20, 2022
7 tasks
Base automatically changed from G1gg1L3s/T2568-substitute-oid-in-parse to master May 24, 2022 09:54
@G1gg1L3s G1gg1L3s merged commit b48b3c0 into master May 24, 2022
@G1gg1L3s G1gg1L3s deleted the G1gg1L3s/T2576-fix-bug-with-i32-encoding branch May 24, 2022 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants