Bug 206317 - Clamp paddingBoxWidth/Height to a minimum of zero
Summary: Clamp paddingBoxWidth/Height to a minimum of zero
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2020-01-15 14:34 PST by Sunny He
Modified: 2020-01-29 20:13 PST (History)
11 users (show)

See Also:


Attachments
Patch (3.97 KB, patch)
2020-01-15 14:45 PST, Sunny He
no flags Details | Formatted Diff | Diff
Patch (6.20 KB, patch)
2020-01-23 14:40 PST, Sunny He
no flags Details | Formatted Diff | Diff
Patch (7.32 KB, patch)
2020-01-23 14:46 PST, Sunny He
no flags Details | Formatted Diff | Diff
Patch (6.78 KB, patch)
2020-01-23 14:50 PST, Sunny He
no flags Details | Formatted Diff | Diff
Patch (3.39 KB, patch)
2020-01-29 14:42 PST, Sunny He
no flags Details | Formatted Diff | Diff
Patch (3.31 KB, patch)
2020-01-29 16:50 PST, Sunny He
no flags Details | Formatted Diff | Diff
Patch (7.10 KB, patch)
2020-01-29 17:40 PST, Sunny He
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sunny He 2020-01-15 14:34:12 PST
Under rare circumstances the computed paddingBoxWidth/Height may become negative, raising the possibility for errors in later computations. Clamp these values to a minimum of zero to ensure this doesn't happen.
Comment 1 Sunny He 2020-01-15 14:34:40 PST
rdar://57102010
Comment 2 Sunny He 2020-01-15 14:45:44 PST
Created attachment 387848 [details]
Patch
Comment 3 Sunny He 2020-01-23 14:40:36 PST
Created attachment 388592 [details]
Patch
Comment 4 Sunny He 2020-01-23 14:46:01 PST
Created attachment 388593 [details]
Patch
Comment 5 Simon Fraser (smfr) 2020-01-23 14:47:20 PST
Comment on attachment 388593 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=388593&action=review

> Source/WebCore/rendering/RenderReplaced.cpp:464
> +    WTFLogAlways("computeConstrainedLogicalWidth logicalWidth=%f, marginStart=%f, marginEnd=%f, size().width()=%f, clientWidth()=%f",
> +        logicalWidth.toFloat(), marginStart.toFloat(), marginEnd.toFloat(), size().width().toFloat(), clientWidth().toFloat());
> +    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + borderLeft() + borderRight() + verticalScrollbarWidth())));
> +    WTFLogAlways("computeConstrainedLogicalWidth final logicalWidth=%f", logicalWidth.toFloat());

No logging please!
Comment 6 Sunny He 2020-01-23 14:50:01 PST
Created attachment 388594 [details]
Patch
Comment 7 Sunny He 2020-01-23 18:08:41 PST
(In reply to Simon Fraser (smfr) from comment #5)
> Comment on attachment 388593 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=388593&action=review
> 
> > Source/WebCore/rendering/RenderReplaced.cpp:464
> > +    WTFLogAlways("computeConstrainedLogicalWidth logicalWidth=%f, marginStart=%f, marginEnd=%f, size().width()=%f, clientWidth()=%f",
> > +        logicalWidth.toFloat(), marginStart.toFloat(), marginEnd.toFloat(), size().width().toFloat(), clientWidth().toFloat());
> > +    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + borderLeft() + borderRight() + verticalScrollbarWidth())));
> > +    WTFLogAlways("computeConstrainedLogicalWidth final logicalWidth=%f", logicalWidth.toFloat());
> 
> No logging please!

Fixed, looks like EWS is happy with this one.
Comment 8 zalan 2020-01-23 18:47:47 PST
Comment on attachment 388594 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=388594&action=review

> Source/WebCore/rendering/RenderReplaced.cpp:461
> -    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + (size().width() - clientWidth()))));
> +    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + borderLeft() + borderRight() + verticalScrollbarWidth())));

I am confused how this works (or even worked before). The logical width here (which is the content logical width) of an inline replaced box is supposed to be the containing block's content box width - (margin start + border inline start + padding inline start + padding inline end + border inline end + margin end), since the constraint equation is as follows containing block's content width = margin s + border s + padding s + content width + padding e + border e + margin e.
It's even in the comment a few lines above.
Comment 9 Darin Adler 2020-01-26 21:30:51 PST
Comment on attachment 388594 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=388594&action=review

> Source/WebCore/rendering/RenderBox.h:221
> +    LayoutUnit paddingBoxWidth() const { return std::max<LayoutUnit>(0, width() - borderLeft() - borderRight() - verticalScrollbarWidth()); }
> +    LayoutUnit paddingBoxHeight() const { return std::max<LayoutUnit>(0, height() - borderTop() - borderBottom() - horizontalScrollbarHeight()); }

A more economical way to write this is "std::max(0_lu,"

>> Source/WebCore/rendering/RenderReplaced.cpp:461
>> +    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + borderLeft() + borderRight() + verticalScrollbarWidth())));
> 
> I am confused how this works (or even worked before). The logical width here (which is the content logical width) of an inline replaced box is supposed to be the containing block's content box width - (margin start + border inline start + padding inline start + padding inline end + border inline end + margin end), since the constraint equation is as follows containing block's content width = margin s + border s + padding s + content width + padding e + border e + margin e.
> It's even in the comment a few lines above.

I am going to say review+ here, but I am concerned that Alan is confused about this, since this is an area he's expert on. Please follow up with him.
Comment 10 zalan 2020-01-28 19:27:38 PST
(In reply to Darin Adler from comment #9)
> Comment on attachment 388594 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=388594&action=review
> 
> > Source/WebCore/rendering/RenderBox.h:221
> > +    LayoutUnit paddingBoxWidth() const { return std::max<LayoutUnit>(0, width() - borderLeft() - borderRight() - verticalScrollbarWidth()); }
> > +    LayoutUnit paddingBoxHeight() const { return std::max<LayoutUnit>(0, height() - borderTop() - borderBottom() - horizontalScrollbarHeight()); }
> 
> A more economical way to write this is "std::max(0_lu,"
> 
> >> Source/WebCore/rendering/RenderReplaced.cpp:461
> >> +    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + borderLeft() + borderRight() + verticalScrollbarWidth())));
> > 
> > I am confused how this works (or even worked before). The logical width here (which is the content logical width) of an inline replaced box is supposed to be the containing block's content box width - (margin start + border inline start + padding inline start + padding inline end + border inline end + margin end), since the constraint equation is as follows containing block's content width = margin s + border s + padding s + content width + padding e + border e + margin e.
> > It's even in the comment a few lines above.
> 
> I am going to say review+ here, but I am concerned that Alan is confused
> about this, since this is an area he's expert on. Please follow up with him.

(In reply to zalan from comment #8)
> Comment on attachment 388594 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=388594&action=review
> 
> > Source/WebCore/rendering/RenderReplaced.cpp:461
> > -    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + (size().width() - clientWidth()))));
> > +    logicalWidth = std::max(0_lu, (logicalWidth - (marginStart + marginEnd + borderLeft() + borderRight() + verticalScrollbarWidth())));
> 
> I am confused how this works (or even worked before). The logical width here
> (which is the content logical width) of an inline replaced box is supposed
> to be the containing block's content box width - (margin start + border
> inline start + padding inline start + padding inline end + border inline end
> + margin end), since the constraint equation is as follows containing
> block's content width = margin s + border s + padding s + content width +
> padding e + border e + margin e.
> It's even in the comment a few lines above.
I guess this is fine since you are not changing behavior here. I am just baffled how incorrect this is (as per https://www.w3.org/TR/CSS22/visudet.html#inline-replaced-width) and specifically that there's even a comment above this line disagreeing with the logic here. I would put a fixme or some kind of explanation why it is ok to have it this way.
Comment 11 zalan 2020-01-28 19:28:10 PST
Please address Darin's comment before landing.
Comment 12 Sunny He 2020-01-29 14:42:59 PST
Created attachment 389189 [details]
Patch
Comment 13 Sunny He 2020-01-29 15:38:49 PST
Comment on attachment 389189 [details]
Patch

Need to take another look at this, just changing to match the spec's expression is clobbering some css tests.
Comment 14 Sunny He 2020-01-29 16:50:18 PST
Created attachment 389201 [details]
Patch
Comment 15 Sunny He 2020-01-29 17:40:36 PST
Created attachment 389207 [details]
Patch
Comment 16 Sunny He 2020-01-29 17:41:14 PST
(In reply to Sunny He from comment #14)
> Created attachment 389201 [details]
> Patch

Figures, missed the tests again.
Comment 17 WebKit Commit Bot 2020-01-29 20:13:02 PST
Comment on attachment 389207 [details]
Patch

Clearing flags on attachment: 389207

Committed r255413: <https://trac.webkit.org/changeset/255413>
Comment 18 WebKit Commit Bot 2020-01-29 20:13:04 PST
All reviewed patches have been landed.  Closing bug.