diff --git a/docs/progress.html b/docs/progress.html
index c6c76c4e..2d6539cb 100644
--- a/docs/progress.html
+++ b/docs/progress.html
@@ -143,7 +143,7 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
border-*-color | COMPOSITE(<color>, transparent) |
border-*-style | ENUM(none, hidden, dotted, dashed,
solid, double, groove, ridge, inset, outset) |
-border-*-width | COMPOSITE(<length>, thin, medium, thick) |
+border-*-width | COMPOSITE(<length>, thin, medium, thick) |
clear | ENUM(none, left, right, both) |
color | <color> |
float | ENUM(left, right, none), May require layout
@@ -158,7 +158,7 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
|
font-weight | ENUM(normal, bold, bolder, lighter,
100, 200, 300, 400, 500, 600, 700, 800, 900), maybe special code for
in-between integers |
-letter-spacing | COMPOSITE(<length>, normal) |
+letter-spacing | COMPOSITE(<length>, normal) |
line-height | COMPOSITE(<number>,
<length>, <percentage>, normal) |
list-style-position | ENUM(inside, outside),
@@ -185,7 +185,7 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
lowercase, none) |
width | COMPOSITE(<length>,
<percentage>, auto), Interesting |
-word-spacing | COMPOSITE(<length>, auto),
+ |
word-spacing | COMPOSITE(<length>, auto),
IE 5 no support |
diff --git a/library/HTMLPurifier/AttrDef/CSSLength.php b/library/HTMLPurifier/AttrDef/CSSLength.php
new file mode 100644
index 00000000..9bf18ba4
--- /dev/null
+++ b/library/HTMLPurifier/AttrDef/CSSLength.php
@@ -0,0 +1,40 @@
+ true, 'ex' => true, 'px' => true, 'in' => true,
+ 'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true);
+ var $number_def;
+
+ function HTMLPurifier_AttrDef_CSSLength($non_negative = false) {
+ $this->number_def = new HTMLPurifier_AttrDef_Number($non_negative);
+ }
+
+ function validate($length, $config, &$context) {
+
+ $length = $this->parseCDATA($length);
+ if ($length === '') return false;
+ if ($length === '0') return '0';
+ $strlen = strlen($length);
+ if ($strlen === 1) return false; // impossible!
+
+ // we assume all units are two characters
+ $unit = substr($length, $strlen - 2);
+ $number = substr($length, 0, $strlen - 2);
+
+ if (!isset($this->units[$unit])) return false;
+
+ $number = $this->number_def->validate($number, $config, $context);
+ if ($number === false) return false;
+
+ return $number . $unit;
+
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/library/HTMLPurifier/AttrDef/Number.php b/library/HTMLPurifier/AttrDef/Number.php
index d596d136..02a80b97 100644
--- a/library/HTMLPurifier/AttrDef/Number.php
+++ b/library/HTMLPurifier/AttrDef/Number.php
@@ -3,6 +3,12 @@
class HTMLPurifier_AttrDef_Number extends HTMLPurifier_AttrDef
{
+ var $non_negative = false;
+
+ function HTMLPurifier_AttrDef_Number($non_negative = false) {
+ $this->non_negative = $non_negative;
+ }
+
function validate($number, $config, &$context) {
$number = $this->parseCDATA($number);
@@ -12,6 +18,7 @@ class HTMLPurifier_AttrDef_Number extends HTMLPurifier_AttrDef
$sign = '';
switch ($number[0]) {
case '-':
+ if ($this->non_negative) return false;
$sign = '-';
case '+':
$number = substr($number, 1);
diff --git a/library/HTMLPurifier/CSSDefinition.php b/library/HTMLPurifier/CSSDefinition.php
index f296fd76..bf56784c 100644
--- a/library/HTMLPurifier/CSSDefinition.php
+++ b/library/HTMLPurifier/CSSDefinition.php
@@ -49,11 +49,29 @@ class HTMLPurifier_CSSDefinition
$this->info['border-bottom-color'] =
$this->info['border-left-color'] =
$this->info['border-right-color'] =
- $this->info['background-color'] = new HTMLPurifier_AttrDef_Composite( array(
+ $this->info['background-color'] = new HTMLPurifier_AttrDef_Composite(array(
new HTMLPurifier_AttrDef_Enum(array('transparent')),
new HTMLPurifier_AttrDef_Color()
));
+ $this->info['border-top-width'] =
+ $this->info['border-bottom-width'] =
+ $this->info['border-left-width'] =
+ $this->info['border-right-width'] = new HTMLPurifier_AttrDef_Composite(array(
+ new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
+ new HTMLPurifier_AttrDef_CSSLength(true) //disallow negative
+ ));
+
+ $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_Composite(array(
+ new HTMLPurifier_AttrDef_Enum(array('normal')),
+ new HTMLPurifier_AttrDef_CSSLength()
+ ));
+
+ $this->info['word-spacing'] = new HTMLPurifier_AttrDef_Composite(array(
+ new HTMLPurifier_AttrDef_Enum(array('normal')),
+ new HTMLPurifier_AttrDef_CSSLength()
+ ));
+
// this could use specialized code
$this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
array('normal', 'bold', 'bolder', 'lighter', '100', '200', '300',
diff --git a/tests/HTMLPurifier/AttrDef/CSSLengthTest.php b/tests/HTMLPurifier/AttrDef/CSSLengthTest.php
new file mode 100644
index 00000000..99722eb3
--- /dev/null
+++ b/tests/HTMLPurifier/AttrDef/CSSLengthTest.php
@@ -0,0 +1,40 @@
+def = new HTMLPurifier_AttrDef_CSSLength();
+
+ $this->assertDef('0');
+ $this->assertDef('0px');
+ $this->assertDef('4.5px');
+ $this->assertDef('-4.5px');
+ $this->assertDef('3ex');
+ $this->assertDef('3em');
+ $this->assertDef('3in');
+ $this->assertDef('3cm');
+ $this->assertDef('3mm');
+ $this->assertDef('3pt');
+ $this->assertDef('3pc');
+
+ $this->assertDef('3', false);
+ $this->assertDef('3miles', false);
+
+ }
+
+ function testNonNegative() {
+
+ $this->def = new HTMLPurifier_AttrDef_CSSLength(true);
+
+ $this->assertDef('3cm');
+ $this->assertDef('-3mm', false);
+
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/tests/HTMLPurifier/AttrDef/CSSTest.php b/tests/HTMLPurifier/AttrDef/CSSTest.php
index ab46d142..3efa21f5 100644
--- a/tests/HTMLPurifier/AttrDef/CSSTest.php
+++ b/tests/HTMLPurifier/AttrDef/CSSTest.php
@@ -24,6 +24,13 @@ class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
$this->assertDef('background-color:transparent;');
$this->assertDef('color:#F00;');
$this->assertDef('border-top-color:#F00;');
+ $this->assertDef('border-top-width:thin;');
+ $this->assertDef('border-top-width:12px;');
+ $this->assertDef('border-top-width:-12px;', false);
+ $this->assertDef('letter-spacing:normal;');
+ $this->assertDef('letter-spacing:2px;');
+ $this->assertDef('word-spacing:normal;');
+ $this->assertDef('word-spacing:3em;');
// duplicates
$this->assertDef('text-align:right;text-align:left;',
diff --git a/tests/HTMLPurifier/AttrDef/NumberTest.php b/tests/HTMLPurifier/AttrDef/NumberTest.php
index 4c6f3b13..3ddb6b5c 100644
--- a/tests/HTMLPurifier/AttrDef/NumberTest.php
+++ b/tests/HTMLPurifier/AttrDef/NumberTest.php
@@ -26,6 +26,14 @@ class HTMLPurifier_AttrDef_NumberTest extends HTMLPurifier_AttrDefHarness
}
+ function testNonNegative() {
+
+ $this->def = new HTMLPurifier_AttrDef_Number(true);
+ $this->assertDef('23');
+ $this->assertDef('-12', false);
+
+ }
+
}
?>
\ No newline at end of file
diff --git a/tests/index.php b/tests/index.php
index c4f00230..d8b477a9 100644
--- a/tests/index.php
+++ b/tests/index.php
@@ -68,6 +68,7 @@ $test_files[] = 'AttrDef/CompositeTest.php';
$test_files[] = 'AttrDef/ColorTest.php';
$test_files[] = 'AttrDef/IntegerTest.php';
$test_files[] = 'AttrDef/NumberTest.php';
+$test_files[] = 'AttrDef/CSSLengthTest.php';
$test_files[] = 'IDAccumulatorTest.php';
$test_files[] = 'TagTransformTest.php';
$test_files[] = 'AttrTransform/LangTest.php';