Use JS module's length calculation for FormData values#241
Use JS module's length calculation for FormData values#241FreeMasen wants to merge 2 commits intobytecodealliance:mainfrom
Conversation
There was a problem hiding this comment.
Hey, thank for looking into this!
I had to refresh my memory on this one. Generally speaking I don't think Variant<JS::Heap<JS::Value>, HostString> will work here because we would need both. Otherwise when calling FormData#get or similar, for the variant holding HostString we would need to call core::decode to get the Value from string.
Overall I see few issues with the code in this patch:
- each call to
JS_GetStringCharAtis internally callingJS_EnsureLinearStringwhich potentially allocates and is very slow for iterating over characters, instead we should get linear string once and operate on its memory directly, JS_EnsureLinearStringis fallible and its return value should be checked againstnullptrcompute_unencoded_normalized_lenfunction should itself be fallible (because of potential allocation failures) so it should returnmozilla::Result.
e.g:
JSString *linear = JS_EnsureLinearString(cx, value);
if (!linear) {
return mozilla::Err;
}
JS::AutoCheckCannotGC nogc;
const char16_t *chars;
size_t length;
if (!JS_GetTwoByteLinearStringCharsAndLength(cx, linear, &chars, &length)) {
return mozilla::Err;
}
size_t defalted_len = JS::GetDeflatedUTF8StringLength(linear);
for (size_t i = 0; i < length; ++i) {
auto c = chars[i];
...
}I appreciate the tests, although in this case I think the WPT test suite coverage for FormData is quite good and the added test feel redundant. You can run the WPT tests like this:
just wpt-setup
just wpt-test
You should see the number of failures if your function is incorrect.
|
Thank you very much for the feedback. I believe I have the changes locally working but will likely not be able to clean them up to push until the evening US Central Time today or tomorrow. |
4d31988 to
a927dab
Compare
| return len; | ||
| } | ||
|
|
||
| std::optional<size_t> compute_unencoded_normalized_len(JSContext *cx, JS::HandleString value) { |
There was a problem hiding this comment.
I ran into an issue resolving with the mozilla::Result type at this level and instead am using std::nullopt as an OOM indicator. If that isn't the right choice I can move this function into the namespace where OutOfMemory is defined.
f9bbf08 to
9ea48dd
Compare
9ea48dd to
00e6a18
Compare
|
All squashed up and ready to merge, thank you for all your support and suggestions while I worked through this |
This is an attempt to address #211 by using
JS::GetDeflatedUTF8StringLengthto avoid encoding while calculating the length of values.This change doesn't follow the suggestion to use
variant<JS::Heap<JS::Value>, HostString>but I believe this would be equivalent to the existing implementation. If it would be preferable to use the memoization approach suggested I would be happy to close this and re-open when I can figure out how to implement that version.Testing
I've added a new test to the
integrationtests explicitly to target length calculation in this path, please feel free to request more test cases.