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

Handle YAML.load_file on Psych 4 #392

Merged
merged 2 commits into from Jan 14, 2022
Merged

Conversation

casperisfine
Copy link
Contributor

Kind of a fix for #375. Not exactly because it doesn't add support for safe_load_file, but for YAML.load_file on psych 4, which is the most used interface.

The idea is that we store a boolean prefix in the cache. When we precompile we try to parse in safe mode, if it fails we fallback to unsafe parsing.

When loading from cache, we know if load_file or unsafe_load_file is used. unsafe_load_file can use cache generated in safe mode, but load_file won't use caches generated via unsafe_load_file.

This is a rough prototype, it misses a few bits and needs a lot more testing.

@casperisfine casperisfine force-pushed the fix-yaml-cache-psych-4-safe-load branch 5 times, most recently from 89158d4 to a95c258 Compare January 13, 2022 14:43
@casperisfine
Copy link
Contributor Author

Ok, found an interesting bug:

File.write("foo.json", "true")
JSON.load_file("foo.json) # => true
YAML.load_file("foo.json) # EOFError

It might seem weird, but since YAML is a superset of JSON, it's not totally invalid, and even if it was we should still fallback properly.

Until now it worked because JSON and YAML caches had the same format. But now that YAML caches have a prefix to indicate wether they are safe mode compatible, YAML can't read JSON caches and vice-versa.

So each cache would need a key prefix or something.

@casperisfine casperisfine force-pushed the fix-yaml-cache-psych-4-safe-load branch 3 times, most recently from aa7d24a to d767c21 Compare January 14, 2022 08:38
@casperisfine casperisfine marked this pull request as ready for review January 14, 2022 09:33
@casperisfine casperisfine force-pushed the fix-yaml-cache-psych-4-safe-load branch from d767c21 to f562d2a Compare January 14, 2022 09:40
@casperisfine
Copy link
Contributor Author

The Windows segfault seem consistent and legit.

@casperisfine casperisfine force-pushed the fix-yaml-cache-psych-4-safe-load branch 3 times, most recently from 24af1d4 to 8400bd0 Compare January 14, 2022 15:25
Context: https://bugs.ruby-lang.org/issues/18492

Rescuing exceptions from a C-extension is complicated, and even seem
a bit broken on Windows.

It's much simpler to return a special unique value, and likely is more performant
too.
@casperisfine casperisfine force-pushed the fix-yaml-cache-psych-4-safe-load branch from 7244cef to f210df9 Compare January 14, 2022 16:58
@casperisfine
Copy link
Contributor Author

Since I ran into https://bugs.ruby-lang.org/issues/18492, I had to refactor further to workaround the issue.

Instead of raising Uncompilable, the API now returns UNCOMPILABLE (specific BasicObject instance). It's probably for the best as raising exceptions is more costly.

cc @peterzhu2118

@casperisfine casperisfine merged commit 91b81c9 into main Jan 14, 2022
@shopify-shipit shopify-shipit bot temporarily deployed to rubygems January 14, 2022 17:06 Inactive
casperisfine pushed a commit to byroot/frozen_record that referenced this pull request Jan 26, 2022
This can cause issues with older versions of Bootsnap

Ref: Shopify/bootsnap#392 (comment)
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