diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-08-04 18:37:10 -0600 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-08-04 18:37:10 -0600 |
commit | b9f00190e1364fb1b9ab8dc089593910c3e34d41 (patch) | |
tree | 3c4a3aa26daa3c538922eda1e74442d9ca750738 /components/layout/generated_content.rs | |
parent | eecd9752093540220eb52308b8fb3ceba0939e3c (diff) | |
parent | 35ba73112395fe97599b8661729b02cedea7609a (diff) | |
download | servo-b9f00190e1364fb1b9ab8dc089593910c3e34d41.tar.gz servo-b9f00190e1364fb1b9ab8dc089593910c3e34d41.zip |
Auto merge of #6979 - mbrubeck:counter, r=pcwalton
Fix crash caused by negative numbers in list counters.
Fixes #6818. The test still fails because of #6978.
r? @pcwalton
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6979)
<!-- Reviewable:end -->
Diffstat (limited to 'components/layout/generated_content.rs')
-rw-r--r-- | components/layout/generated_content.rs | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs index 6e9f5da9918..8bac6d0b973 100644 --- a/components/layout/generated_content.rs +++ b/components/layout/generated_content.rs @@ -531,37 +531,57 @@ pub fn static_representation(list_style_type: list_style_type::T) -> char { /// Pushes the string that represents the value rendered using the given *alphabetic system* onto /// the accumulator per CSS-COUNTER-STYLES § 3.1.4. fn push_alphabetic_representation(mut value: i32, system: &[char], accumulator: &mut String) { + let mut abs_value = handle_negative_value(value, accumulator); + let mut string: SmallVec<[char; 8]> = SmallVec::new(); - while value != 0 { + while abs_value != 0 { // Step 1. - value = value - 1; + abs_value = abs_value - 1; // Step 2. - string.push(system[(value as usize) % system.len()]); + string.push(system[abs_value % system.len()]); // Step 3. - value = ((value as usize) / system.len()) as i32; + abs_value = abs_value / system.len(); } accumulator.extend(string.iter().cloned().rev()) } /// Pushes the string that represents the value rendered using the given *numeric system* onto the -/// accumulator per CSS-COUNTER-STYLES § 3.1.4. +/// accumulator per CSS-COUNTER-STYLES § 3.1.5. fn push_numeric_representation(mut value: i32, system: &[char], accumulator: &mut String) { + let mut abs_value = handle_negative_value(value, accumulator); + // Step 1. - if value == 0 { + if abs_value == 0 { accumulator.push(system[0]); return } // Step 2. let mut string: SmallVec<[char; 8]> = SmallVec::new(); - while value != 0 { + while abs_value != 0 { // Step 2.1. - string.push(system[(value as usize) % system.len()]); + string.push(system[abs_value % system.len()]); // Step 2.2. - value = ((value as usize) / system.len()) as i32; + abs_value = abs_value / system.len(); } // Step 3. accumulator.extend(string.iter().cloned().rev()) } + +/// If the system uses a negative sign, handle negative values per CSS-COUNTER-STYLES § 2. +/// +/// Returns the absolute value of the counter. +fn handle_negative_value(value: i32, accumulator: &mut String) -> usize { + // 3. If the counter value is negative and the counter style uses a negative sign, instead + // generate an initial representation using the absolute value of the counter value. + if value < 0 { + // TODO: Support different negative signs using the 'negative' descriptor. + // https://drafts.csswg.org/date/2015-07-16/css-counter-styles/#counter-style-negative + accumulator.push('-'); + value.abs() as usize + } else { + value as usize + } +} |