Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.2k
querystring: fix empty pairs handling#11234
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
mscdex commented Feb 8, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
This commit fixes handling of empty pairs that occur before the end of the query string so that they are also ignored. Additionally, some optimizations have been made, including: * Avoid unnecessary code execution where possible * Use a lookup table when checking for hex characters * Avoid forced decoding when '+' characters are encountered and we are using the default decoder Fixes: nodejs#10454
71973b3 to 7b72507Compare| encodeCheck=1; | ||
| continue; | ||
| }elseif(encodeCheck>0){ | ||
| // eslint-disable-next-line no-extra-boolean-cast |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anyone is curious, this was added because there seems to be a positive difference when explicitly converting to a boolean in the conditional vs. implicitly converting the numeric value (or undefined) to a boolean. eslint doesn't know that isHexTable contains non-booleans, so I explicitly silence these "errors."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it better to use isHexTable[code] > 0 as a more readable option? The performance seems to be quite similar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's debatable. I think the explicit conversion is easier to reason about than remembering how undefined values compare with numeric values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, in this case I'd propose isHexTable[code] === 1 as an alternative
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anyone is curious, this was added because there seems to be a positive difference when explicitly converting to a boolean in the conditional vs. implicitly converting the numeric value (or undefined) to a boolean.
Could you clarify what you mean by the "positive difference"?
mscdexFeb 10, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you clarify what you mean by the "positive difference"?
An increase in performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's interesting. AFAIK if (foo) has exactly the same behavior as if (!!foo), so I'm not sure why the performance would be different.
If there really is a difference, then I propose adding a comment explaining that.
| // timed loop. Instead, just execute the function a "sufficient" number of | ||
| // times before the timed loop to ensure the function is optimized just once. | ||
| if(type==='multicharsep'){ | ||
| for(i=0;i<n;i+=1) |
joyeecheungFeb 8, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be n? Refs: v8/src/runtime-profiler.cc, this might change but 1e3 should probabaly be safe.
// Number of times a function has to be seen on the stack before it is// compiled for baseline.staticconstintkProfilerTicksBeforeBaseline = 1; // Number of times a function has to be seen on the stack before it is// optimized.staticconstintkProfilerTicksBeforeOptimization = 2; // If the function optimization was disabled due to high deoptimization count,// but the function is hot and has been seen on the stack this number of times,// then we try to reenable optimization for this function.staticconstintkProfilerTicksBeforeReenablingOptimization = 250; // If a function does not have enough type info (according to// FLAG_type_info_threshold), but has seen a huge number of ticks,// optimize it as it is.staticconstintkTicksWhenNotEnoughTypeInfo = 100; // We only have one byte to store the number of ticks.STATIC_ASSERT(kProfilerTicksBeforeOptimization < 256); STATIC_ASSERT(kProfilerTicksBeforeReenablingOptimization < 256); STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I used n / 2, but I seemed to get better (less variable) results with n, especially considering the default value of n. Either way, nshould be enough no matter what, so I kept it.
stevenvachon commented Feb 9, 2017
Please merge asap. |
mscdex commented Feb 9, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@stevenvachon Other @nodejs/collaborators need to sign off on this first. |
stevenvachon commented Feb 13, 2017
Hate to nag, but how about now? I'd really like to play with this in a nightly build. |
This commit fixes handling of empty pairs that occur before the end of the query string so that they are also ignored. Additionally, some optimizations have been made, including: * Avoid unnecessary code execution where possible * Use a lookup table when checking for hex characters * Avoid forced decoding when '+' characters are encountered and we are using the default decoder Fixes: #10454 PR-URL: #11234 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]>
PR-URL: #11234 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Nicu Micleușanu <[email protected]>
jasnell commented Feb 13, 2017
Landed in ff785fd...8bcc122 |
This specific bug was fixed by #11234. This commit turns on the tests accordingly. PR-URL: #11369 Ref: #11234 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Timothy Gu <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
stevenvachon commented Feb 28, 2017
This has a "dont-land-on-v7.x" label, yet it appears to be working in v7.6 |
mscdex commented Feb 28, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@stevenvachon This didn't land in v7.x. Can you explain what you mean by "working?" For example, I should also point out that |
stevenvachon commented Feb 28, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
This issue was referenced in #11171 as the solution. My comment there, containing a test case that was failing on 7.5.x is now passing on 7.6 |
mscdex commented Feb 28, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@stevenvachon With the test case you're referencing I get the same result on node v0.10.41, v4.0.0, v6.5.0, v7.5.0, v7.6.0, and master: |
stevenvachon commented Feb 28, 2017
Shit.. I dunno what's going on then. My original issue is not reproducible with 7.5, which was available days before posting. |
mscdex commented Feb 28, 2017 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
@stevenvachon Ah ok, so that was originally using WHATWG URL, which does its parsing in a specific way and its implementation has changed often since node v7.0.0. FWIW though I tried node v7.4.0, v7.5.0, and v7.6.0 and got the same expected result you showed in your original issue, namely: |
stevenvachon commented Feb 28, 2017
Thank you. Sorry for wasting space in here. I'll have to update a number of test suites as I'd built around this supposed issue. |
This is a follow up to #10967, which is (currently) a semver-major.
This PR fixes outstanding issues stemming from the aforementioned PR and includes the tests from #11171. FWIW the original issue for all of this was that empty query string key/value pairs before the end of the string were not being ignored like an empty key/value at the end of the string would be.
I've also included some improvements to the parser in general, along with a couple of new benchmarks to highlight some of those improvements. Here are the results for benchmark/querystring/querystring-parse.js:
CI: https://ci.nodejs.org/job/node-test-pull-request/6279/
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)