diff --git a/NEWS b/NEWS index 374fc627..e602f617 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,7 @@ ERRATA use this rather than __construct(), although legacy code using constructors will still work--the new format, however, lets modules access the configuration object for HTML namespace dependant tweaks. +. AttrDef_HTML_Pixels now takes a single construction parameter, pixels. 2.1.4, released 2008-05-18 ! DefinitionCacheFactory now can register new implementations diff --git a/library/HTMLPurifier/AttrDef/CSS/Length.php b/library/HTMLPurifier/AttrDef/CSS/Length.php index 9df33bb9..79ac5bff 100644 --- a/library/HTMLPurifier/AttrDef/CSS/Length.php +++ b/library/HTMLPurifier/AttrDef/CSS/Length.php @@ -3,20 +3,6 @@ require_once 'HTMLPurifier/Length.php'; require_once 'HTMLPurifier/UnitConverter.php'; -HTMLPurifier_ConfigSchema::define( - 'CSS', 'MaxImgLength', '1200px', 'string/null', ' -

- This parameter sets the maximum allowed length on img tags, - effectively the width and height properties. - Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is - in place to prevent imagecrash attacks, disable with null at your own risk. - This directive is similar to %HTML.MaxImgLength, and both should be - concurrently edited, although there are - subtle differences in the input format (the CSS max is a number with - a unit). -

-'); - /** * Represents a Length as defined by CSS. */ diff --git a/library/HTMLPurifier/AttrDef/HTML/Pixels.php b/library/HTMLPurifier/AttrDef/HTML/Pixels.php index 38bc7d68..ad206151 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Pixels.php +++ b/library/HTMLPurifier/AttrDef/HTML/Pixels.php @@ -8,6 +8,12 @@ require_once 'HTMLPurifier/AttrDef.php'; class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef { + var $max; + + function HTMLPurifier_AttrDef_HTML_Pixels($max = null) { + $this->max = $max; + } + function validate($string, $config, &$context) { $string = trim($string); @@ -26,11 +32,18 @@ class HTMLPurifier_AttrDef_HTML_Pixels extends HTMLPurifier_AttrDef // crash operating systems, see // WARNING, above link WILL crash you if you're using Windows - if ($int > 1200) return '1200'; + if ($this->max !== null && $int > $this->max) return (string) $this->max; return (string) $int; } + function make($string) { + if ($string === '') $max = null; + else $max = (int) $string; + $class = get_class($this); + return new $class($max); + } + } diff --git a/library/HTMLPurifier/CSSDefinition.php b/library/HTMLPurifier/CSSDefinition.php index d986b907..cec5ccf0 100644 --- a/library/HTMLPurifier/CSSDefinition.php +++ b/library/HTMLPurifier/CSSDefinition.php @@ -27,6 +27,20 @@ HTMLPurifier_ConfigSchema::define(

'); +HTMLPurifier_ConfigSchema::define( + 'CSS', 'MaxImgLength', '1200px', 'string/null', ' +

+ This parameter sets the maximum allowed length on img tags, + effectively the width and height properties. + Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %HTML.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the CSS max is a number with + a unit). +

+'); + /** * Defines allowed CSS attributes and what their values are. * @see HTMLPurifier_HTMLDefinition @@ -176,21 +190,25 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition new HTMLPurifier_AttrDef_CSS_Percentage() )); + $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + new HTMLPurifier_AttrDef_Enum(array('auto')) + )); + $max = $config->get('CSS', 'MaxImgLength'); $this->info['width'] = $this->info['height'] = - new HTMLPurifier_AttrDef_Switch('img', - // For img tags: - new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length('0', $config->get('CSS', 'MaxImgLength')), - new HTMLPurifier_AttrDef_Enum(array('auto')) - )), - // For everyone else: - new HTMLPurifier_AttrDef_CSS_Composite(array( - new HTMLPurifier_AttrDef_CSS_Length('0'), - new HTMLPurifier_AttrDef_CSS_Percentage(true), - new HTMLPurifier_AttrDef_Enum(array('auto')) - )) - ); + $max === null ? + $trusted_wh : + new HTMLPurifier_AttrDef_Switch('img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Composite(array( + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + new HTMLPurifier_AttrDef_Enum(array('auto')) + )), + // For everyone else: + $trusted_wh + ); $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); diff --git a/library/HTMLPurifier/HTMLModule/Image.php b/library/HTMLPurifier/HTMLModule/Image.php index 16b2f921..b6f14f64 100644 --- a/library/HTMLPurifier/HTMLModule/Image.php +++ b/library/HTMLPurifier/HTMLModule/Image.php @@ -5,6 +5,18 @@ require_once 'HTMLPurifier/HTMLModule.php'; require_once 'HTMLPurifier/AttrDef/URI.php'; require_once 'HTMLPurifier/AttrTransform/ImgRequired.php'; +HTMLPurifier_ConfigSchema::define( + 'HTML', 'MaxImgLength', 1200, 'int/null', ' +

+ This directive controls the maximum number of pixels in the width and + height attributes in img tags. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %CSS.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the HTML max is an integer). +

+'); + /** * XHTML 1.1 Image Module provides basic image embedding. * @note There is specialized code for removing empty images in @@ -16,6 +28,7 @@ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule var $name = 'Image'; function setup($config) { + $max = $config->get('HTML', 'MaxImgLength'); $img =& $this->addElement( 'img', true, 'Inline', 'Empty', 'Common', array( @@ -23,12 +36,17 @@ class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule // According to the spec, it's Length, but percents can // be abused, so we allow only Pixels. A trusted module // could overload this with the real value. - 'height' => 'Pixels', - 'width' => 'Pixels', + 'height' => 'Pixels#' . $max, + 'width' => 'Pixels#' . $max, 'longdesc' => 'URI', 'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded ) ); + if ($max === null || $config->get('HTML', 'Trusted')) { + $img->attr['height'] = + $img->attr['width'] = 'Length'; + } + // kind of strange, but splitting things up would be inefficient $img->attr_transform_pre[] = $img->attr_transform_post[] = diff --git a/tests/HTMLPurifier/AttrDef/HTML/PixelsTest.php b/tests/HTMLPurifier/AttrDef/HTML/PixelsTest.php index 6fa899bf..7aeb838e 100644 --- a/tests/HTMLPurifier/AttrDef/HTML/PixelsTest.php +++ b/tests/HTMLPurifier/AttrDef/HTML/PixelsTest.php @@ -36,5 +36,12 @@ class HTMLPurifier_AttrDef_HTML_PixelsTest extends HTMLPurifier_AttrDefHarness } + function test_make() { + $factory = new HTMLPurifier_AttrDef_HTML_Pixels(); + $this->def = $factory->make('30'); + $this->assertDef('25'); + $this->assertDef('35', '30'); + } + } diff --git a/tests/HTMLPurifier/HTMLModule/ImageTest.php b/tests/HTMLPurifier/HTMLModule/ImageTest.php new file mode 100644 index 00000000..50764c5a --- /dev/null +++ b/tests/HTMLPurifier/HTMLModule/ImageTest.php @@ -0,0 +1,57 @@ +assertResult(''); + } + + function testLengthTooLarge() { + $this->assertResult( + '', + '' + ); + } + + function testLengthPercentage() { + $this->assertResult( + '', + '' + ); + } + + function testLengthCustomMax() { + $this->config->set('HTML', 'MaxImgLength', 20); + $this->assertResult( + '', + '' + ); + } + + function testLengthCrashFixDisabled() { + $this->config->set('HTML', 'MaxImgLength', null); + $this->assertResult( + '' + ); + $this->assertResult( + '' + ); + } + + function testLengthTrusted() { + $this->config->set('HTML', 'Trusted', true); + $this->assertResult( + '' + ); + $this->assertResult( + '' + ); + } + +} + diff --git a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php index 5b837414..7ce2f1d9 100644 --- a/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php +++ b/tests/HTMLPurifier/Strategy/ValidateAttributesTest.php @@ -208,6 +208,13 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends ); } + function testKeepPercentCSSWidthAndHeightOnImgWhenToldTo() { + $this->config->set('CSS', 'MaxImgLength', null); + $this->assertResult( + '' + ); + } + function testRemoveRelativeCSSWidthAndHeightOnImg() { $this->assertResult( '', diff --git a/tests/test_files.php b/tests/test_files.php index 463f635f..3368da49 100644 --- a/tests/test_files.php +++ b/tests/test_files.php @@ -80,6 +80,7 @@ $test_files[] = 'HTMLPurifier/GeneratorTest.php'; $test_files[] = 'HTMLPurifier/HTMLDefinitionTest.php'; $test_files[] = 'HTMLPurifier/HTMLModuleManagerTest.php'; $test_files[] = 'HTMLPurifier/HTMLModuleTest.php'; +$test_files[] = 'HTMLPurifier/HTMLModule/ImageTest.php'; $test_files[] = 'HTMLPurifier/HTMLModule/ObjectTest.php'; $test_files[] = 'HTMLPurifier/HTMLModule/RubyTest.php'; $test_files[] = 'HTMLPurifier/HTMLModule/ScriptingTest.php';