LibWeb: Saturate list-item ordinal numbering at the i32 bounds
Problem: Crash when loading an ordered list whose numbering reaches the i32 limit; e.g. <ol start="2147483647"> with two or more items. Cause: Element::ordinal_value() kept its numbering in a Checked<i32> and stepped it once per list item. When the numbering already sits at the i32 maximum (or minimum, for a reversed list whose value attribute pins it there), the increment overflowed the Checked value. Fix: Keep the numbering in a plain i32 instead, and step it with AK::saturating_add and AK::saturating_sub — so it clamps at the i32 bounds, rather than overflowing. Fixes https://github.com/LadybirdBrowser/ladybird/issues/10003
This commit is contained in:
parent
9ffd3e48c3
commit
86f75e1e35
3 changed files with 19 additions and 4 deletions
|
|
@ -13,6 +13,7 @@
|
|||
#include <AK/IterationDecision.h>
|
||||
#include <AK/JsonObjectSerializer.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/SaturatingMath.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/DecodedImageFrame.h>
|
||||
|
|
@ -4208,7 +4209,7 @@ i32 Element::ordinal_value()
|
|||
|
||||
// 1. Let i be 1. [Not necessary]
|
||||
// 2. If owner is an ol element, let numbering be owner's starting value. Otherwise, let numbering be 1.
|
||||
AK::Checked<i32> numbering = 1;
|
||||
i32 numbering = 1;
|
||||
auto reversed = false;
|
||||
|
||||
if (auto* ol_element = as_if<HTML::HTMLOListElement>(owner.ptr())) {
|
||||
|
|
@ -4233,13 +4234,13 @@ i32 Element::ordinal_value()
|
|||
}
|
||||
|
||||
// 6. The ordinal value of item is numbering.
|
||||
item->m_ordinal_value = numbering.value();
|
||||
item->m_ordinal_value = numbering;
|
||||
|
||||
// 7. If owner is an ol element, and owner has a reversed attribute, decrement numbering by 1; otherwise, increment numbering by 1.
|
||||
if (reversed) {
|
||||
numbering--;
|
||||
numbering = AK::saturating_sub(numbering, 1);
|
||||
} else {
|
||||
numbering++;
|
||||
numbering = AK::saturating_add(numbering, 1);
|
||||
}
|
||||
|
||||
// 8. Increment i by 1. [Not necessary]
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
PASS (didn't crash)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="include.js"></script>
|
||||
<!-- Starting value at the i32 maximum: incrementing the ordinal for the second item overflows. -->
|
||||
<ol start="2147483647"><li>a</li><li>b</li></ol>
|
||||
<!-- Reversed list whose value attribute pins the ordinal to the i32 minimum: decrementing underflows. -->
|
||||
<ol reversed><li value="-2147483648">a</li><li>b</li></ol>
|
||||
<script>
|
||||
test(() => {
|
||||
// Forces layout, which computes each list item's ordinal value via the marker box.
|
||||
document.documentElement.offsetHeight;
|
||||
println("PASS (didn't crash)");
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in a new issue