RESOLVED FIXED 188475
[IntersectionObserver] Validate threshold values
https://bugs.webkit.org/show_bug.cgi?id=188475
Summary [IntersectionObserver] Validate threshold values
Ali Juma
Reported 2018-08-10 11:03:20 PDT
Throw an exception if any of the thresholds are outside the range [0, 1].
Attachments
Patch (5.31 KB, patch)
2018-08-10 11:05 PDT, Ali Juma
no flags
Patch (10.21 KB, patch)
2018-08-13 13:47 PDT, Ali Juma
no flags
Ali Juma
Comment 1 2018-08-10 11:05:55 PDT
Darin Adler
Comment 2 2018-08-13 11:03:50 PDT
Comment on attachment 346912 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=346912&action=review > Source/WebCore/page/IntersectionObserver.cpp:94 > + Vector<double> thresholds; > + if (WTF::holds_alternative<double>(init.threshold)) > + thresholds.append(WTF::get<double>(init.threshold)); > + else > + thresholds = WTF::get<Vector<double>>(WTFMove(init.threshold)); I realize this code is just being moved not newly written, but two thoughts: 1) This kind of thing typically reads better with the "switchOn" style that you can find elsewhere in WebKit code -- makes it clearer all cases are handled even when there are just two cases; it is a little more wordy, though. 2) It is probably slightly more efficient to make the Vector in a way that indicates it will have only one double in it, even though it will be deallocated soon after. One way is to use reserveInitialCapacity(1) and then uncheckedAppend rather than just append. Another way is to write something like "thresholds = Vector<double> { 1, init.threshold }", a third way is "thresholds = Vector<Double> { { threshold } };". All of these have the benefit that the vector capacity will be 1 rather than a larger size as part of optimizing growth. > Source/WebCore/page/IntersectionObserver.cpp:97 > + if (threshold < 0 || threshold > 1) For floating point, it’s typically a good practice to take advantage of the property that "NaN" comparisons all return false, so we would instead write: if (!(threshold >= 0 && threshold <=1)) This would give us an exception when one of the values is a NaN. Perhaps that’s already handled at the bindings layer, though. I think we should make sure we have a test that covers NaN (and infinity and other interesting floating point values like denormalized ones), and then still consider the above syntax since it’s better when NaN is involved and I don’t see a lot of downside to writing it this way. Another consideration is that this approach looks good if we decide put the "validity rule" into a small inline function: if (!isValidThreshold(threshold)) So it’s kind of logical to do the one that has a "not" in it. > LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt:4 > PASS IntersectionObserver constructor witth { rootMargin: "1" } Typo in the test here.
Ali Juma
Comment 3 2018-08-13 13:47:00 PDT
Ali Juma
Comment 4 2018-08-13 13:51:55 PDT
Comment on attachment 346912 [details] Patch Thanks for the review! View in context: https://bugs.webkit.org/attachment.cgi?id=346912&action=review >> Source/WebCore/page/IntersectionObserver.cpp:94 >> + thresholds = WTF::get<Vector<double>>(WTFMove(init.threshold)); > > I realize this code is just being moved not newly written, but two thoughts: > > 1) This kind of thing typically reads better with the "switchOn" style that you can find elsewhere in WebKit code -- makes it clearer all cases are handled even when there are just two cases; it is a little more wordy, though. > > 2) It is probably slightly more efficient to make the Vector in a way that indicates it will have only one double in it, even though it will be deallocated soon after. One way is to use reserveInitialCapacity(1) and then uncheckedAppend rather than just append. Another way is to write something like "thresholds = Vector<double> { 1, init.threshold }", a third way is "thresholds = Vector<Double> { { threshold } };". All of these have the benefit that the vector capacity will be 1 rather than a larger size as part of optimizing growth. 1) Changed to use the switchOn style. 2) Used the reserveInitialCapacity(1) approach. >> Source/WebCore/page/IntersectionObserver.cpp:97 >> + if (threshold < 0 || threshold > 1) > > For floating point, it’s typically a good practice to take advantage of the property that "NaN" comparisons all return false, so we would instead write: > > if (!(threshold >= 0 && threshold <=1)) > > This would give us an exception when one of the values is a NaN. Perhaps that’s already handled at the bindings layer, though. I think we should make sure we have a test that covers NaN (and infinity and other interesting floating point values like denormalized ones), and then still consider the above syntax since it’s better when NaN is involved and I don’t see a lot of downside to writing it this way. > > Another consideration is that this approach looks good if we decide put the "validity rule" into a small inline function: > > if (!isValidThreshold(threshold)) > > So it’s kind of logical to do the one that has a "not" in it. Done. It turns out that Nan and infinity are indeed handled already at the bindings layer, but added test coverage nevertheless. >> LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt:4 >> PASS IntersectionObserver constructor witth { rootMargin: "1" } > > Typo in the test here. Fixed. Fixed it upstream as well.
WebKit Commit Bot
Comment 5 2018-08-13 15:02:52 PDT
Comment on attachment 347034 [details] Patch Clearing flags on attachment: 347034 Committed r234818: <https://trac.webkit.org/changeset/234818>
WebKit Commit Bot
Comment 6 2018-08-13 15:02:53 PDT
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 7 2018-08-13 15:03:26 PDT
Note You need to log in before you can comment on or make changes to this bug.