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 thread safety issue with encoding tables #515

Merged
merged 2 commits into from Jul 31, 2023

Conversation

casperisfine
Copy link
Contributor

Fix: #514
Fix: oracle/truffleruby#3166

These hashes lazily memoize percent encoded characters, this is an issue on GVL-less Ruby implementations as it can cause concurrent access.

But these are actually quite wasteful as the key is always a single byte so rather than use string keys are lazily memoize these, we can precompute two static arrays of 255 elements once and for all.

@eregon @dentarg

NB: I'm not a big addressable user, so I mostly relied on the test suite, hopefully my assertions are correct.

@casperisfine casperisfine force-pushed the precompute-constants branch 2 times, most recently from 07511f2 to b54a4bc Compare July 31, 2023 09:02
Copy link
Contributor

@eregon eregon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks much simpler, thank you!

end.join('|')})"
bytes = leave_encoded.bytes
leave_encoded_downcase = bytes.map { |b| SEQUENCE_ENCODING_TABLE[b] }.join('|')
leave_encoded_upcase = bytes.map { |b| SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[b] }.join('|')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE has extra %:

SEQUENCE_ENCODING_TABLE[
> format("%02x", 45)
=> "2d"
SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE
> format("%%%02X", 45)
=> "%2D"

So it should be without the % because that's already present outside (|%)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, I think you are right, but it's weird because I didn't change that 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nevermind, I get it now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be good now.

Fix: sporkmonger#514
Fix: oracle/truffleruby#3166

These hashes lazily memoize percent encoded characters, this is an
issue on GVL-less Ruby implementations as it can cause concurrent
access.

But these are actually quite wastful as the key is always a single byte
so rather than use string keys are lazily memoize these, we can precompute
two static arrays of 255 elements once and for all.
@dentarg
Copy link
Collaborator

dentarg commented Jul 31, 2023

What do we think about the ruby-head failure? double free or corruption (out) (maybe it is unrelated to this change, we'll see)

@casperisfine
Copy link
Contributor Author

casperisfine commented Jul 31, 2023

maybe it is unrelated to this change

It is. Addressable being pure Ruby, it can in no way be responsible for a VM crash of this sort.

dentarg added a commit to dentarg/addressable that referenced this pull request Jul 31, 2023
@dentarg dentarg mentioned this pull request Jul 31, 2023
dentarg added a commit that referenced this pull request Jul 31, 2023
@dentarg dentarg merged commit e01456b into sporkmonger:main Jul 31, 2023
33 checks passed
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.

Unsafe concurrent Hash access Java exception escaping Hash#[]= in addressable
4 participants