Bug 839809: Make counter-increments and list counting that would go past our internal (int32_t) limit keep the counter at its current value rather than wrapping. r=dholbert

Per CSS WG resolution regarding counter-styles-3, afternoon of 2013-02-05:
http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590
http://lists.w3.org/Archives/Public/www-style/2013Feb/0392.html

Note that this patch depends on signed integer overflow behavior in C++,
which I believe is portable despite being unspecified.
This commit is contained in:
L. David Baron 2013-02-21 18:10:59 -08:00
parent 221ad89967
commit 61dc418096
17 changed files with 413 additions and 2 deletions

View File

@ -58,7 +58,8 @@ void nsCounterChangeNode::Calc(nsCounterList *aList)
mValueAfter = mChangeValue;
} else {
NS_ASSERTION(mType == INCREMENT, "invalid type");
mValueAfter = aList->ValueBefore(this) + mChangeValue;
mValueAfter = nsCounterManager::IncrementCounter(aList->ValueBefore(this),
mChangeValue);
}
}

View File

@ -229,6 +229,21 @@ public:
void Dump();
#endif
static int32_t IncrementCounter(int32_t aOldValue, int32_t aIncrement)
{
int32_t newValue = aOldValue + aIncrement;
// The CSS Working Group resolved that a counter-increment that
// exceeds internal limits should not increment at all.
// http://lists.w3.org/Archives/Public/www-style/2013Feb/0392.html
// (This means, for example, that if aIncrement is 5, the
// counter will get stuck at the largest multiple of 5 less than
// the maximum 32-bit integer.)
if ((aIncrement > 0) != (newValue > aOldValue)) {
newValue = aOldValue;
}
return newValue;
}
private:
// for |AddCounterResetsAndIncrements| only
bool AddResetOrIncrement(nsIFrame *aFrame, int32_t aIndex,

View File

@ -6691,6 +6691,9 @@ nsBlockFrame::RenumberLists(nsPresContext* aPresContext)
for (nsIContent* kid = mContent->GetFirstChild(); kid;
kid = kid->GetNextSibling()) {
if (kid->IsHTML(nsGkAtoms::li)) {
// FIXME: This isn't right in terms of what CSS says to do for
// overflow of counters (but it only matters when this node has
// more than numeric_limits<int32_t>::max() children).
ordinal -= increment;
}
}

View File

@ -21,6 +21,7 @@
#include "nsNetUtil.h"
#include "prprf.h"
#include "nsDisplayList.h"
#include "nsCounterManager.h"
#include "imgILoader.h"
#include "imgIContainer.h"
@ -417,7 +418,7 @@ nsBulletFrame::SetListItemOrdinal(int32_t aNextOrdinal,
*aChanged = oldOrdinal != mOrdinal;
return mOrdinal + aIncrement;
return nsCounterManager::IncrementCounter(mOrdinal, aIncrement);
}

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
</head>
<body>
<div id="test">
<span>2147483646</span>
<span>2147483647</span>
<span>2147483647</span>
<span>2147483647</span>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
#test { counter-reset: c 2147483645; }
#test span { counter-increment: c; }
#test span:before { content: counter(c); }
</style>
</head>
<body>
<div id="test">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
</head>
<body>
<div id="test">
<span>2147483640</span>
<span>2147483645</span>
<span>2147483645</span>
<span>2147483645</span>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
#test { counter-reset: c 2147483635; }
#test span { counter-increment: c 5; }
#test span:before { content: counter(c); }
</style>
</head>
<body>
<div id="test">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
</head>
<body>
<div id="test">
<span>-2147483646</span>
<span>-2147483647</span>
<span>-2147483648</span>
<span>-2147483648</span>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
#test { counter-reset: c -2147483645; }
#test span { counter-increment: c -1; }
#test span:before { content: counter(c); }
</style>
</head>
<body>
<div id="test">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
</head>
<body>
<div id="test">
<span>-2147483640</span>
<span>-2147483645</span>
<span>-2147483645</span>
<span>-2147483645</span>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>css-counter-styles-3 Test Suite: content: counter(c)</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
#test { counter-reset: c -2147483635; }
#test span { counter-increment: c -5; }
#test span:before { content: counter(c); }
</style>
</head>
<body>
<div id="test">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>test of counter UA overflow rules for HTML lists</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec. It also can't be contributed because it's testing HTML
lists.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
ol { margin-left: 10em; padding-left: 0; }
li { margin-left: 0; padding-left: 0 }
</style>
</head>
<body>
<ol>
<li value="2147483646">Alpha
<li value="2147483647">Bravo
<li value="2147483647">Charlie
<li value="2147483647">Delta
</ol>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>test of counter UA overflow rules for HTML lists</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec. It also can't be contributed because it's testing HTML
lists.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
ol { margin-left: 10em; padding-left: 0; }
li { margin-left: 0; padding-left: 0 }
</style>
</head>
<body>
<ol start="2147483646">
<li>Alpha
<li>Bravo
<li>Charlie
<li>Delta
</ol>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>test of counter UA overflow rules for HTML lists</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec. It also can't be contributed because it's testing HTML
lists.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
ol { margin-left: 10em; padding-left: 0; }
li { margin-left: 0; padding-left: 0 }
li.hidden { visibility: hidden; height: 0 }
ol { margin-bottom: 0 }
ol + ol { margin-top: 0 }
</style>
</head>
<body>
<!--
Work around our inability to parse -2147483648 as an HTML integer attribute
(Bug 586761)
-->
<ol reversed start="-2147483645">
<li class="hidden">hidden
<li>Alpha
</ol>
<ol reversed start="-2147483646">
<li class="hidden">hidden
<li>Bravo
</ol>
<ol reversed start="-2147483647">
<li class="hidden">hidden
<li>Charlie
</ol>
<ol reversed start="-2147483647">
<li class="hidden">hidden
<li>Delta
</ol>
</body>
</html>

View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>test of counter UA overflow rules for HTML lists</title>
<!--
NOTE: This test cannot be contributed to the test suite because
it presumes a 4-byte unsigned integer, which is not required by
the spec. It also can't be contributed because it's testing HTML
lists.
However, it tests the rules for what happens at the UA-specific
limit, which are required by the spec.
-->
<link rel="help" href="http://dev.w3.org/csswg/css-counter-styles-3/#counter-style-range"/>
<link rel="help" href="http://krijnhoetmer.nl/irc-logs/css/20130205#l-1590"/>
<style type="text/css">
ol { margin-left: 10em; padding-left: 0; }
li { margin-left: 0; padding-left: 0 }
</style>
</head>
<body>
<ol reversed start="-2147483646">
<li>Alpha
<li>Bravo
<li>Charlie
<li>Delta
</ol>
</body>
</html>

View File

@ -61,3 +61,9 @@
== counter-hebrew-test.html counter-hebrew-reference.html
== counters-hebrew-test.html counters-hebrew-reference.html
== counter-reset-integer-range.html counter-reset-integer-range-ref.html
== counter-ua-limits-00.html counter-ua-limits-00-ref.html
== counter-ua-limits-01.html counter-ua-limits-01-ref.html
== counter-ua-limits-02.html counter-ua-limits-02-ref.html
== counter-ua-limits-03.html counter-ua-limits-03-ref.html
== counter-ua-limits-list-00.html counter-ua-limits-list-00-ref.html
== counter-ua-limits-list-01.html counter-ua-limits-list-01-ref.html