1
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2025-07-13 10:46:17 +02:00

[2.1.5] [MFH] Round up imagecrash support with HTML.MaxImgLength

git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/branches/php4@1789 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang
2008-06-11 17:38:25 +00:00
parent 3540ea7fce
commit 72f5819ef6
9 changed files with 138 additions and 30 deletions

1
NEWS
View File

@ -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

View File

@ -3,20 +3,6 @@
require_once 'HTMLPurifier/Length.php';
require_once 'HTMLPurifier/UnitConverter.php';
HTMLPurifier_ConfigSchema::define(
'CSS', 'MaxImgLength', '1200px', 'string/null', '
<p>
This parameter sets the maximum allowed length on <code>img</code> tags,
effectively the <code>width</code> and <code>height</code> 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).
</p>
');
/**
* Represents a Length as defined by CSS.
*/

View File

@ -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 <http://ha.ckers.org/imagecrash.html>
// 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);
}
}

View File

@ -27,6 +27,20 @@ HTMLPurifier_ConfigSchema::define(
</p>
');
HTMLPurifier_ConfigSchema::define(
'CSS', 'MaxImgLength', '1200px', 'string/null', '
<p>
This parameter sets the maximum allowed length on <code>img</code> tags,
effectively the <code>width</code> and <code>height</code> 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).
</p>
');
/**
* Defines allowed CSS attributes and what their values are.
* @see HTMLPurifier_HTMLDefinition
@ -176,20 +190,24 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_CSS_Percentage()
));
$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(
$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'] =
$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();

View File

@ -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', '
<p>
This directive controls the maximum number of pixels in the width and
height attributes in <code>img</code> 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).
</p>
');
/**
* 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[] =

View File

@ -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');
}
}

View File

@ -0,0 +1,57 @@
<?php
require_once 'HTMLPurifier/HTMLModuleHarness.php';
require_once 'HTMLPurifier/HTMLModule/Image.php';
class HTMLPurifier_HTMLModule_ImageTest extends HTMLPurifier_HTMLModuleHarness
{
function testNormal() {
$this->assertResult('<img height="40" width="40" src="" alt="" />');
}
function testLengthTooLarge() {
$this->assertResult(
'<img height="40000" width="40000" src="" alt="" />',
'<img height="1200" width="1200" src="" alt="" />'
);
}
function testLengthPercentage() {
$this->assertResult(
'<img height="100%" width="100%" src="" alt="" />',
'<img src="" alt="" />'
);
}
function testLengthCustomMax() {
$this->config->set('HTML', 'MaxImgLength', 20);
$this->assertResult(
'<img height="30" width="30" src="" alt="" />',
'<img height="20" width="20" src="" alt="" />'
);
}
function testLengthCrashFixDisabled() {
$this->config->set('HTML', 'MaxImgLength', null);
$this->assertResult(
'<img height="100%" width="100%" src="" alt="" />'
);
$this->assertResult(
'<img height="40000" width="40000" src="" alt="" />'
);
}
function testLengthTrusted() {
$this->config->set('HTML', 'Trusted', true);
$this->assertResult(
'<img height="100%" width="100%" src="" alt="" />'
);
$this->assertResult(
'<img height="40000" width="40000" src="" alt="" />'
);
}
}

View File

@ -208,6 +208,13 @@ class HTMLPurifier_Strategy_ValidateAttributesTest extends
);
}
function testKeepPercentCSSWidthAndHeightOnImgWhenToldTo() {
$this->config->set('CSS', 'MaxImgLength', null);
$this->assertResult(
'<img src="" alt="" style="width:100%;height:100%;border:1px solid #000;" />'
);
}
function testRemoveRelativeCSSWidthAndHeightOnImg() {
$this->assertResult(
'<img src="" alt="" style="width:10em;height:10em;border:1px solid #000;" />',

View File

@ -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';