Number.php 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <?php
  2. /**
  3. * Validates a number as defined by the CSS spec.
  4. */
  5. class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
  6. {
  7. /**
  8. * Indicates whether or not only positive values are allowed.
  9. * @type bool
  10. */
  11. protected $non_negative = false;
  12. /**
  13. * @param bool $non_negative indicates whether negatives are forbidden
  14. */
  15. public function __construct($non_negative = false)
  16. {
  17. $this->non_negative = $non_negative;
  18. }
  19. /**
  20. * @param string $number
  21. * @param HTMLPurifier_Config $config
  22. * @param HTMLPurifier_Context $context
  23. * @return string|bool
  24. * @warning Some contexts do not pass $config, $context. These
  25. * variables should not be used without checking HTMLPurifier_Length
  26. */
  27. public function validate($number, $config, $context)
  28. {
  29. $number = $this->parseCDATA($number);
  30. if ($number === '') {
  31. return false;
  32. }
  33. if ($number === '0') {
  34. return '0';
  35. }
  36. $sign = '';
  37. switch ($number[0]) {
  38. case '-':
  39. if ($this->non_negative) {
  40. return false;
  41. }
  42. $sign = '-';
  43. case '+':
  44. $number = substr($number, 1);
  45. }
  46. if (ctype_digit($number)) {
  47. $number = ltrim($number, '0');
  48. return $number ? $sign . $number : '0';
  49. }
  50. // Period is the only non-numeric character allowed
  51. if (strpos($number, '.') === false) {
  52. return false;
  53. }
  54. list($left, $right) = explode('.', $number, 2);
  55. if ($left === '' && $right === '') {
  56. return false;
  57. }
  58. if ($left !== '' && !ctype_digit($left)) {
  59. return false;
  60. }
  61. // Remove leading zeros until positive number or a zero stays left
  62. if (ltrim($left, '0') != '') {
  63. $left = ltrim($left, '0');
  64. } else {
  65. $left = '0';
  66. }
  67. $right = rtrim($right, '0');
  68. if ($right === '') {
  69. return $left ? $sign . $left : '0';
  70. } elseif (!ctype_digit($right)) {
  71. return false;
  72. }
  73. return $sign . $left . '.' . $right;
  74. }
  75. }
  76. // vim: et sw=4 sts=4