FontFamily.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. /**
  3. * Validates a font family list according to CSS spec
  4. * @todo whitelisting allowed fonts would be nice
  5. */
  6. class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
  7. {
  8. public function validate($string, $config, $context) {
  9. static $generic_names = array(
  10. 'serif' => true,
  11. 'sans-serif' => true,
  12. 'monospace' => true,
  13. 'fantasy' => true,
  14. 'cursive' => true
  15. );
  16. // assume that no font names contain commas in them
  17. $fonts = explode(',', $string);
  18. $final = '';
  19. foreach($fonts as $font) {
  20. $font = trim($font);
  21. if ($font === '') continue;
  22. // match a generic name
  23. if (isset($generic_names[$font])) {
  24. $final .= $font . ', ';
  25. continue;
  26. }
  27. // match a quoted name
  28. if ($font[0] === '"' || $font[0] === "'") {
  29. $length = strlen($font);
  30. if ($length <= 2) continue;
  31. $quote = $font[0];
  32. if ($font[$length - 1] !== $quote) continue;
  33. $font = substr($font, 1, $length - 2);
  34. }
  35. $font = $this->expandCSSEscape($font);
  36. // $font is a pure representation of the font name
  37. if (ctype_alnum($font) && $font !== '') {
  38. // very simple font, allow it in unharmed
  39. $final .= $font . ', ';
  40. continue;
  41. }
  42. // bugger out on whitespace. form feed (0C) really
  43. // shouldn't show up regardless
  44. $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font);
  45. // These ugly transforms don't pose a security
  46. // risk (as \\ and \" might). We could try to be clever and
  47. // use single-quote wrapping when there is a double quote
  48. // present, but I have choosen not to implement that.
  49. // (warning: this code relies on the selection of quotation
  50. // mark below)
  51. $font = str_replace('\\', '\\5C ', $font);
  52. $font = str_replace('"', '\\22 ', $font);
  53. // complicated font, requires quoting
  54. $final .= "\"$font\", "; // note that this will later get turned into &quot;
  55. }
  56. $final = rtrim($final, ', ');
  57. if ($final === '') return false;
  58. return $final;
  59. }
  60. }
  61. // vim: et sw=4 sts=4