Bug 188475 - [IntersectionObserver] Validate threshold values
Summary: [IntersectionObserver] Validate threshold values
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Ali Juma
URL:
Keywords: InRadar
Depends on:
Blocks: 159475
  Show dependency treegraph
 
Reported: 2018-08-10 11:03 PDT by Ali Juma
Modified: 2018-08-13 15:03 PDT (History)
6 users (show)

See Also:


Attachments
Patch (5.31 KB, patch)
2018-08-10 11:05 PDT, Ali Juma
no flags Details | Formatted Diff | Diff
Patch (10.21 KB, patch)
2018-08-13 13:47 PDT, Ali Juma
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ali Juma 2018-08-10 11:03:20 PDT
Throw an exception if any of the thresholds are outside the range [0, 1].
Comment 1 Ali Juma 2018-08-10 11:05:55 PDT
Created attachment 346912 [details]
Patch
Comment 2 Darin Adler 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.
Comment 3 Ali Juma 2018-08-13 13:47:00 PDT
Created attachment 347034 [details]
Patch
Comment 4 Ali Juma 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.
Comment 5 WebKit Commit Bot 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>
Comment 6 WebKit Commit Bot 2018-08-13 15:02:53 PDT
All reviewed patches have been landed.  Closing bug.
Comment 7 Radar WebKit Bug Importer 2018-08-13 15:03:26 PDT
<rdar://problem/43254352>