浏览代码

LibWeb: Limit `HTMLTableCellElement` rowSpan to allowed values

This change ensures that `rowSpan` is clamped to the maximum value of
65534 if the given value is larger than 2147483647.
Tim Ledbetter 7 月之前
父节点
当前提交
9fc2a63131

+ 16 - 6
Libraries/LibWeb/HTML/HTMLTableCellElement.cpp

@@ -147,21 +147,31 @@ WebIDL::ExceptionOr<void> HTMLTableCellElement::set_col_span(WebIDL::UnsignedLon
 
 
 // This implements step 9 in the spec here:
 // This implements step 9 in the spec here:
 // https://html.spec.whatwg.org/multipage/tables.html#algorithm-for-processing-rows
 // https://html.spec.whatwg.org/multipage/tables.html#algorithm-for-processing-rows
-unsigned int HTMLTableCellElement::row_span() const
+WebIDL::UnsignedLong HTMLTableCellElement::row_span() const
 {
 {
+    auto row_span_attribute = get_attribute(HTML::AttributeNames::rowspan);
+    if (!row_span_attribute.has_value())
+        return 1;
+
     // If parsing that value failed or if the attribute is absent, then let rowspan be 1, instead.
     // If parsing that value failed or if the attribute is absent, then let rowspan be 1, instead.
-    auto value = Web::HTML::parse_non_negative_integer(get_attribute_value(HTML::AttributeNames::rowspan)).value_or(1);
+    auto optional_value_digits = Web::HTML::parse_non_negative_integer_digits(*row_span_attribute);
+    if (!optional_value_digits.has_value())
+        return 1;
+
+    auto optional_value = optional_value_digits->to_number<i64>(TrimWhitespace::No);
 
 
     // If rowspan is greater than 65534, let it be 65534 instead.
     // If rowspan is greater than 65534, let it be 65534 instead.
-    if (value > 65534) {
+    // NOTE: If there is no value at this point the value must be larger than NumericLimits<i64>::max(), so return the maximum value of 65534.
+    if (!optional_value.has_value() || *optional_value > 65534)
         return 65534;
         return 65534;
-    }
 
 
-    return value;
+    return *optional_value;
 }
 }
 
 
-WebIDL::ExceptionOr<void> HTMLTableCellElement::set_row_span(unsigned int value)
+WebIDL::ExceptionOr<void> HTMLTableCellElement::set_row_span(WebIDL::UnsignedLong value)
 {
 {
+    if (value > 2147483647)
+        value = 1;
     return set_attribute(HTML::AttributeNames::rowspan, String::number(value));
     return set_attribute(HTML::AttributeNames::rowspan, String::number(value));
 }
 }
 
 

+ 2 - 2
Libraries/LibWeb/HTML/HTMLTableCellElement.h

@@ -19,10 +19,10 @@ public:
     virtual ~HTMLTableCellElement() override;
     virtual ~HTMLTableCellElement() override;
 
 
     WebIDL::UnsignedLong col_span() const;
     WebIDL::UnsignedLong col_span() const;
-    unsigned row_span() const;
+    WebIDL::UnsignedLong row_span() const;
 
 
     WebIDL::ExceptionOr<void> set_col_span(WebIDL::UnsignedLong);
     WebIDL::ExceptionOr<void> set_col_span(WebIDL::UnsignedLong);
-    WebIDL::ExceptionOr<void> set_row_span(unsigned);
+    WebIDL::ExceptionOr<void> set_row_span(WebIDL::UnsignedLong);
 
 
     WebIDL::Long cell_index() const;
     WebIDL::Long cell_index() const;
 
 

+ 24 - 0
Tests/LibWeb/Text/expected/HTML/unsigned-long-reflection.txt

@@ -328,6 +328,30 @@ td.getAttribute("colspan") after td.setAttribute("colSpan", "4294967296"): 42949
 td.colSpan after td.setAttribute("colspan", "4294967296"): 1000
 td.colSpan after td.setAttribute("colspan", "4294967296"): 1000
 td.getAttribute("colspan") after td.colSpan = 4294967296: 0
 td.getAttribute("colspan") after td.colSpan = 4294967296: 0
 td.colSpan after td.colSpan = 4294967296: 1
 td.colSpan after td.colSpan = 4294967296: 1
+td.getAttribute("rowspan") after td.setAttribute("rowSpan", "0"): 0
+td.rowSpan after td.setAttribute("rowspan", "0"): 0
+td.getAttribute("rowspan") after td.rowSpan = 0: 0
+td.rowSpan after td.rowSpan = 0: 0
+td.getAttribute("rowspan") after td.setAttribute("rowSpan", "1"): 1
+td.rowSpan after td.setAttribute("rowspan", "1"): 1
+td.getAttribute("rowspan") after td.rowSpan = 1: 1
+td.rowSpan after td.rowSpan = 1: 1
+td.getAttribute("rowspan") after td.setAttribute("rowSpan", "2147483647"): 2147483647
+td.rowSpan after td.setAttribute("rowspan", "2147483647"): 65534
+td.getAttribute("rowspan") after td.rowSpan = 2147483647: 2147483647
+td.rowSpan after td.rowSpan = 2147483647: 65534
+td.getAttribute("rowspan") after td.setAttribute("rowSpan", "2147483648"): 2147483648
+td.rowSpan after td.setAttribute("rowspan", "2147483648"): 65534
+td.getAttribute("rowspan") after td.rowSpan = 2147483648: 1
+td.rowSpan after td.rowSpan = 2147483648: 1
+td.getAttribute("rowspan") after td.setAttribute("rowSpan", "4294967295"): 4294967295
+td.rowSpan after td.setAttribute("rowspan", "4294967295"): 65534
+td.getAttribute("rowspan") after td.rowSpan = 4294967295: 1
+td.rowSpan after td.rowSpan = 4294967295: 1
+td.getAttribute("rowspan") after td.setAttribute("rowSpan", "4294967296"): 4294967296
+td.rowSpan after td.setAttribute("rowspan", "4294967296"): 65534
+td.getAttribute("rowspan") after td.rowSpan = 4294967296: 0
+td.rowSpan after td.rowSpan = 4294967296: 0
 textarea.getAttribute("maxlength") after textarea.setAttribute("maxLength", "0"): 0
 textarea.getAttribute("maxlength") after textarea.setAttribute("maxLength", "0"): 0
 textarea.maxLength after textarea.setAttribute("maxlength", "0"): 0
 textarea.maxLength after textarea.setAttribute("maxlength", "0"): 0
 textarea.getAttribute("maxlength") after textarea.maxLength = 0: 0
 textarea.getAttribute("maxlength") after textarea.maxLength = 0: 0

+ 1 - 0
Tests/LibWeb/Text/input/HTML/unsigned-long-reflection.html

@@ -57,6 +57,7 @@
         testProperty("marquee", "scrollDelay", (marquee) => marquee.scrollDelay, (marquee, value) => marquee.scrollDelay = value);
         testProperty("marquee", "scrollDelay", (marquee) => marquee.scrollDelay, (marquee, value) => marquee.scrollDelay = value);
         testProperty("select", "size", (select) => select.size, (select, value) => select.size = value);
         testProperty("select", "size", (select) => select.size, (select, value) => select.size = value);
         testProperty("td", "colSpan", (tableCell) => tableCell.colSpan, (tableCell, value) => tableCell.colSpan = value);
         testProperty("td", "colSpan", (tableCell) => tableCell.colSpan, (tableCell, value) => tableCell.colSpan = value);
+        testProperty("td", "rowSpan", (tableCell) => tableCell.rowSpan, (tableCell, value) => tableCell.rowSpan = value);
         testProperty("textarea", "maxLength", (textarea) => textarea.maxLength, (textarea, value) => textarea.maxLength = value);
         testProperty("textarea", "maxLength", (textarea) => textarea.maxLength, (textarea, value) => textarea.maxLength = value);
         testProperty("textarea", "minLength", (textarea) => textarea.minLength, (textarea, value) => textarea.minLength = value);
         testProperty("textarea", "minLength", (textarea) => textarea.minLength, (textarea, value) => textarea.minLength = value);
         testProperty("textarea", "rows", (textarea) => textarea.rows, (textarea, value) => textarea.rows = value);
         testProperty("textarea", "rows", (textarea) => textarea.rows, (textarea, value) => textarea.rows = value);