mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-01-03 05:11:52 +00:00
MOODLE-556: Added some types for MathML attributes to restrict use of CDATA
This commit is contained in:
parent
12b1110bf6
commit
ad34dd3841
25
library/HTMLPurifier/AttrDef/MathML/Character.php
Normal file
25
library/HTMLPurifier/AttrDef/MathML/Character.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the MathML attribute character.
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrDef_MathML_Character extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $char
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($char, $config, $context)
|
||||
{
|
||||
if (mb_strlen($char) == 1 && strpos(' \t\n\r', $char) === false) {
|
||||
return $char;
|
||||
} elseif (preg_match('/&((#[0-9]+)|(#x[0-9A-Fa-f]+)|([0-9A-Za-z]+));/', $char)) {
|
||||
return $char;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
44
library/HTMLPurifier/AttrDef/MathML/Color.php
Normal file
44
library/HTMLPurifier/AttrDef/MathML/Color.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates Color as defined by MathML.
|
||||
*/
|
||||
class HTMLPurifier_AttrDef_MathML_Color extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
// MathML 3 only accepts HTML4 color names + transparent
|
||||
static protected $colornames = array(
|
||||
'aqua',
|
||||
'black',
|
||||
'blue',
|
||||
'fuchsia',
|
||||
'gray',
|
||||
'green',
|
||||
'lime',
|
||||
'maroon',
|
||||
'navy',
|
||||
'olive',
|
||||
'purple',
|
||||
'red',
|
||||
'silver',
|
||||
'teal',
|
||||
'white',
|
||||
'yellow',
|
||||
'transparent'
|
||||
);
|
||||
|
||||
public function validate($color, $config, $context)
|
||||
{
|
||||
|
||||
$color = trim($color);
|
||||
|
||||
if (preg_match('/(#[0-9A-Fa-f]{3})|(#[0-9A-Fa-f]{6})/', $color) || in_array(strtolower($color), static::$colornames)) {
|
||||
return $color;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vim: et sw=4 sts=4
|
36
library/HTMLPurifier/AttrDef/MathML/Length.php
Normal file
36
library/HTMLPurifier/AttrDef/MathML/Length.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Validates the MathML type length (not to be confused with either HTML nor
|
||||
* CSS's length).
|
||||
*/
|
||||
|
||||
class HTMLPurifier_AttrDef_MathML_Length extends HTMLPurifier_AttrDef
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $string
|
||||
* @param HTMLPurifier_Config $config
|
||||
* @param HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate($string, $config, $context)
|
||||
{
|
||||
$string = $this->parseCDATA($string);
|
||||
|
||||
// Optimizations
|
||||
if ($string === '') {
|
||||
return false;
|
||||
}
|
||||
if ($string === '0') {
|
||||
return '0';
|
||||
}
|
||||
|
||||
$length = HTMLPurifier_MathMLLength::make($string);
|
||||
if (!$length->isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $length->toString();
|
||||
}
|
||||
}
|
@ -50,10 +50,23 @@ class HTMLPurifier_AttrTypes
|
||||
|
||||
// "proprietary" types
|
||||
$this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class();
|
||||
$this->info['CSS'] = new HTMLPurifier_AttrDef_CSS();
|
||||
|
||||
// number is really a positive integer (one or more digits)
|
||||
// FIXME: ^^ not always, see start and value of list items
|
||||
$this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true);
|
||||
|
||||
// MathML types
|
||||
$this->info['MathML_ID'] = new HTMLPurifier_AttrDef_MathML_ID();
|
||||
$this->info['MathML_Length'] = new HTMLPurifier_AttrDef_MathML_Length();
|
||||
$this->info['MathML_UnsignedInteger'] = new HTMLPurifier_AttrDef_Integer(false, true, true);
|
||||
$this->info['MathML_PositiveInteger'] = new HTMLPurifier_AttrDef_Integer(false, false, true);
|
||||
$this->info['MathML_Integer'] = new HTMLPurifier_AttrDef_Integer(true, true, true);
|
||||
$this->info['MathML_UnsignedNumber'] = new HTMLPurifier_AttrDef_CSS_Number(true);
|
||||
$this->info['MathML_Number'] = new HTMLPurifier_AttrDef_CSS_Number(false);
|
||||
$this->info['MathML_Character'] = new HTMLPurifier_AttrDef_MathML_Character();
|
||||
$this->info['MathML_Color'] = new HTMLPurifier_AttrDef_MathML_Color();
|
||||
|
||||
}
|
||||
|
||||
private static function makeEnum($in)
|
||||
|
@ -82,10 +82,10 @@ class HTMLPurifier_HTMLModule_MathML extends HTMLPurifier_HTMLModule
|
||||
$E['XLINK.prefix'] . ':type' => 'CDATA',
|
||||
'xml:lang' => 'CDATA',
|
||||
'xml:space' => 'Enum#default,preserve',
|
||||
'id' => new HTMLPurifier_AttrDef_MathML_ID(), // MathML allows multiple elements with same ID
|
||||
'xref' => new HTMLPurifier_AttrDef_MathML_ID(),
|
||||
'id' => 'MathML_ID', // MathML allows multiple elements with same ID
|
||||
'xref' => 'MathML_ID',
|
||||
'class' => 'Class',
|
||||
'style' => new HTMLPurifier_AttrDef_CSS(),
|
||||
'style' => 'CSS',
|
||||
'href' => 'URI',
|
||||
'other' => 'CDATA',
|
||||
),
|
||||
@ -1442,16 +1442,16 @@ class HTMLPurifier_HTMLModule_MathML extends HTMLPurifier_HTMLModule
|
||||
$E['mpadded-length'] = 'CDATA';
|
||||
$E['linestyle'] = 'Enum#none,solid,dashed';
|
||||
$E['columnalignstyle'] = 'Enum#left,center,right';
|
||||
$E['unsigned-integer'] = 'CDATA';
|
||||
$E['integer'] = 'CDATA';
|
||||
$E['number'] = 'CDATA';
|
||||
$E['character'] = 'CDATA';
|
||||
$E['color'] = 'CDATA';
|
||||
$E['positive-integer'] = 'CDATA';
|
||||
$E['unsigned-integer'] = 'MathML_UnsignedInteger';
|
||||
$E['integer'] = 'MathML_Integer';
|
||||
$E['number'] = 'MathML_Number';
|
||||
$E['character'] = 'MathML_Character';
|
||||
$E['color'] = 'MathML_Color';
|
||||
$E['positive-integer'] = 'MathML_PositiveInteger';
|
||||
|
||||
$E['token.content'] = '#PCDATA|mglyph|malignmark';
|
||||
|
||||
$E['length'] = 'CDATA';
|
||||
$E['length'] = 'MathML_Length';
|
||||
$E['DeprecatedTokenAtt'] = array(
|
||||
'fontfamily' => 'CDATA',
|
||||
'fontweight' => 'Enum#normal,bold',
|
||||
@ -2167,7 +2167,8 @@ class HTMLPurifier_HTMLModule_MathML extends HTMLPurifier_HTMLModule
|
||||
array_merge(
|
||||
$CCPAtt,
|
||||
array(
|
||||
'actiontype*' => 'CDATA',
|
||||
// Using 'actiontype*' removes maction element altogether
|
||||
'actiontype' => 'CDATA',
|
||||
'selection' => $E['positive-integer'],
|
||||
)
|
||||
)
|
||||
|
@ -81,7 +81,8 @@ class HTMLPurifier_Length
|
||||
if (!ctype_lower($this->unit)) {
|
||||
$this->unit = strtolower($this->unit);
|
||||
}
|
||||
if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) {
|
||||
if (!isset(static::$allowedUnits[$this->unit]) &&
|
||||
!(isset(static::$allowedUnits['']) && $this->unit === false)) {
|
||||
return false;
|
||||
}
|
||||
// Hack:
|
||||
|
136
library/HTMLPurifier/MathMLLength.php
Normal file
136
library/HTMLPurifier/MathMLLength.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Represents a length in MathML. These admit namedspace values.
|
||||
*/
|
||||
class HTMLPurifier_MathMLLength extends HTMLPurifier_Length
|
||||
{
|
||||
|
||||
/**
|
||||
* One of the specified namedspaces.
|
||||
* @type string
|
||||
*/
|
||||
protected $namedspace;
|
||||
|
||||
/**
|
||||
* Array Lookup array of namedspaces recognized by MathML
|
||||
* @type array
|
||||
*/
|
||||
protected static $allowedNamedspaces = array(
|
||||
'veryverythinmathspace' => true,
|
||||
'verythinmathspace' => true,
|
||||
'thinmathspace' => true,
|
||||
'mediummathspace' => true,
|
||||
'thickmathspace' => true,
|
||||
'verythickmathspace' => true,
|
||||
'veryverythickmathspace' => true,
|
||||
'negativeveryverythinmathspace' => true,
|
||||
'negativeverythinmathspace' => true,
|
||||
'negativethinmathspace' => true,
|
||||
'negativemediummathspace' => true,
|
||||
'negativethickmathspace' => true,
|
||||
'negativeverythickmathspace' => true,
|
||||
'negativeveryverythickmathspace' => true
|
||||
);
|
||||
|
||||
/**
|
||||
* Array Lookup array of units recognized by MathML.
|
||||
* @note This is a restriction of HTMLPurifier_Length's allowed units.
|
||||
* @type array
|
||||
*/
|
||||
protected static $allowedUnits = array(
|
||||
'em' => true, 'ex' => true, 'px' => true, 'in' => true,
|
||||
'cm' => true, 'mm' => true, 'pt' => true, 'pc' => true,
|
||||
'%' => true, '' => true
|
||||
);
|
||||
|
||||
/**
|
||||
* @param string $n Magnitude
|
||||
* @param bool|string $u Unit
|
||||
*/
|
||||
public function __construct($n = '0', $u = false, $namedspace = '')
|
||||
{
|
||||
if ($namedspace) {
|
||||
$this->namedspace = strtolower($namedspace);
|
||||
} else {
|
||||
$this->n = (string) $n;
|
||||
$this->unit = $u !== false ? (string) $u : false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $s Unit string, like '2em' or '3.4in', or namedspace
|
||||
* @return HTMLPurifier_MathMLLength
|
||||
* @warning Does not perform validation.
|
||||
*/
|
||||
public static function make($s)
|
||||
{
|
||||
if ($s instanceof HTMLPurifier_MathMLLength) {
|
||||
return $s;
|
||||
}
|
||||
if (isset(HTMLPurifier_MathMLLength::$allowedNamedspaces[trim($s)])) {
|
||||
return new HTMLPurifier_MathMLLength('0', false, $s);
|
||||
}
|
||||
$length = HTMLPurifier_Length::make($s);
|
||||
return new HTMLPurifier_MathMLLength($length->n, $length->unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the number and unit or namedspace.
|
||||
* @return bool
|
||||
*/
|
||||
protected function validate()
|
||||
{
|
||||
if (isset(HTMLPurifier_MathMLLength::$allowedNamedspaces[$this->namedspace])) {
|
||||
return true;
|
||||
}
|
||||
return parent::validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string representation of number.
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
if (!$this->isValid()) {
|
||||
return false;
|
||||
}
|
||||
if ($this->namedspace) {
|
||||
return $this->namedspace;
|
||||
}
|
||||
return parent::toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the namedspace.
|
||||
* @return string
|
||||
*/
|
||||
public function getNamedspace()
|
||||
{
|
||||
return $this->namedspace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two lengths, and returns 1 if greater, -1 if less, 0 if equal
|
||||
* and null if not comparable.
|
||||
* @param HTMLPurifier_Length $l
|
||||
* @return int
|
||||
* @warning If both values are too large or small, this calculation will
|
||||
* not work properly
|
||||
*/
|
||||
public function compareTo($l)
|
||||
{
|
||||
if ($l === false) {
|
||||
return false;
|
||||
}
|
||||
if ($this->namedspace || $l->namedspace) {
|
||||
if ($this->namedspace === $l->namedspace) {
|
||||
return 0;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return parent::compareTo($l);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user