| 1: | <?php
|
| 2: |
|
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: | |
| 10: | |
| 11: | |
| 12: | |
| 13: | |
| 14: | |
| 15: | |
| 16: |
|
| 17: | class HTMLPurifier_Config
|
| 18: | {
|
| 19: |
|
| 20: | |
| 21: | |
| 22: | |
| 23: |
|
| 24: | public $version = '4.15.0';
|
| 25: |
|
| 26: | |
| 27: | |
| 28: | |
| 29: | |
| 30: |
|
| 31: | public $autoFinalize = true;
|
| 32: |
|
| 33: |
|
| 34: |
|
| 35: | |
| 36: | |
| 37: | |
| 38: | |
| 39: |
|
| 40: | protected $serials = array();
|
| 41: |
|
| 42: | |
| 43: | |
| 44: | |
| 45: |
|
| 46: | protected $serial;
|
| 47: |
|
| 48: | |
| 49: | |
| 50: | |
| 51: |
|
| 52: | protected $parser = null;
|
| 53: |
|
| 54: | |
| 55: | |
| 56: | |
| 57: | |
| 58: | |
| 59: |
|
| 60: | public $def;
|
| 61: |
|
| 62: | |
| 63: | |
| 64: | |
| 65: |
|
| 66: | protected $definitions;
|
| 67: |
|
| 68: | |
| 69: | |
| 70: | |
| 71: |
|
| 72: | protected $finalized = false;
|
| 73: |
|
| 74: | |
| 75: | |
| 76: | |
| 77: |
|
| 78: | protected $plist;
|
| 79: |
|
| 80: | |
| 81: | |
| 82: | |
| 83: |
|
| 84: | private $aliasMode;
|
| 85: |
|
| 86: | |
| 87: | |
| 88: | |
| 89: | |
| 90: | |
| 91: |
|
| 92: | public $chatty = true;
|
| 93: |
|
| 94: | |
| 95: | |
| 96: | |
| 97: |
|
| 98: | private $lock;
|
| 99: |
|
| 100: | |
| 101: | |
| 102: | |
| 103: | |
| 104: | |
| 105: |
|
| 106: | public function __construct($definition, $parent = null)
|
| 107: | {
|
| 108: | $parent = $parent ? $parent : $definition->defaultPlist;
|
| 109: | $this->plist = new HTMLPurifier_PropertyList($parent);
|
| 110: | $this->def = $definition;
|
| 111: | $this->parser = new HTMLPurifier_VarParser_Flexible();
|
| 112: | }
|
| 113: |
|
| 114: | |
| 115: | |
| 116: | |
| 117: | |
| 118: | |
| 119: | |
| 120: | |
| 121: | |
| 122: |
|
| 123: | public static function create($config, $schema = null)
|
| 124: | {
|
| 125: | if ($config instanceof HTMLPurifier_Config) {
|
| 126: |
|
| 127: | return $config;
|
| 128: | }
|
| 129: | if (!$schema) {
|
| 130: | $ret = HTMLPurifier_Config::createDefault();
|
| 131: | } else {
|
| 132: | $ret = new HTMLPurifier_Config($schema);
|
| 133: | }
|
| 134: | if (is_string($config)) {
|
| 135: | $ret->loadIni($config);
|
| 136: | } elseif (is_array($config)) $ret->loadArray($config);
|
| 137: | return $ret;
|
| 138: | }
|
| 139: |
|
| 140: | |
| 141: | |
| 142: | |
| 143: | |
| 144: |
|
| 145: | public static function inherit(HTMLPurifier_Config $config)
|
| 146: | {
|
| 147: | return new HTMLPurifier_Config($config->def, $config->plist);
|
| 148: | }
|
| 149: |
|
| 150: | |
| 151: | |
| 152: | |
| 153: |
|
| 154: | public static function createDefault()
|
| 155: | {
|
| 156: | $definition = HTMLPurifier_ConfigSchema::instance();
|
| 157: | $config = new HTMLPurifier_Config($definition);
|
| 158: | return $config;
|
| 159: | }
|
| 160: |
|
| 161: | |
| 162: | |
| 163: | |
| 164: | |
| 165: | |
| 166: | |
| 167: | |
| 168: |
|
| 169: | public function get($key, $a = null)
|
| 170: | {
|
| 171: | if ($a !== null) {
|
| 172: | $this->triggerError(
|
| 173: | "Using deprecated API: use \$config->get('$key.$a') instead",
|
| 174: | E_USER_WARNING
|
| 175: | );
|
| 176: | $key = "$key.$a";
|
| 177: | }
|
| 178: | if (!$this->finalized) {
|
| 179: | $this->autoFinalize();
|
| 180: | }
|
| 181: | if (!isset($this->def->info[$key])) {
|
| 182: |
|
| 183: | $this->triggerError(
|
| 184: | 'Cannot retrieve value of undefined directive ' . htmlspecialchars($key),
|
| 185: | E_USER_WARNING
|
| 186: | );
|
| 187: | return;
|
| 188: | }
|
| 189: | if (isset($this->def->info[$key]->isAlias)) {
|
| 190: | $d = $this->def->info[$key];
|
| 191: | $this->triggerError(
|
| 192: | 'Cannot get value from aliased directive, use real name ' . $d->key,
|
| 193: | E_USER_ERROR
|
| 194: | );
|
| 195: | return;
|
| 196: | }
|
| 197: | if ($this->lock) {
|
| 198: | list($ns) = explode('.', $key);
|
| 199: | if ($ns !== $this->lock) {
|
| 200: | $this->triggerError(
|
| 201: | 'Cannot get value of namespace ' . $ns . ' when lock for ' .
|
| 202: | $this->lock .
|
| 203: | ' is active, this probably indicates a Definition setup method ' .
|
| 204: | 'is accessing directives that are not within its namespace',
|
| 205: | E_USER_ERROR
|
| 206: | );
|
| 207: | return;
|
| 208: | }
|
| 209: | }
|
| 210: | return $this->plist->get($key);
|
| 211: | }
|
| 212: |
|
| 213: | |
| 214: | |
| 215: | |
| 216: | |
| 217: | |
| 218: | |
| 219: |
|
| 220: | public function getBatch($namespace)
|
| 221: | {
|
| 222: | if (!$this->finalized) {
|
| 223: | $this->autoFinalize();
|
| 224: | }
|
| 225: | $full = $this->getAll();
|
| 226: | if (!isset($full[$namespace])) {
|
| 227: | $this->triggerError(
|
| 228: | 'Cannot retrieve undefined namespace ' .
|
| 229: | htmlspecialchars($namespace),
|
| 230: | E_USER_WARNING
|
| 231: | );
|
| 232: | return;
|
| 233: | }
|
| 234: | return $full[$namespace];
|
| 235: | }
|
| 236: |
|
| 237: | |
| 238: | |
| 239: | |
| 240: | |
| 241: | |
| 242: | |
| 243: | |
| 244: | |
| 245: | |
| 246: |
|
| 247: | public function getBatchSerial($namespace)
|
| 248: | {
|
| 249: | if (empty($this->serials[$namespace])) {
|
| 250: | $batch = $this->getBatch($namespace);
|
| 251: | unset($batch['DefinitionRev']);
|
| 252: | $this->serials[$namespace] = sha1(serialize($batch));
|
| 253: | }
|
| 254: | return $this->serials[$namespace];
|
| 255: | }
|
| 256: |
|
| 257: | |
| 258: | |
| 259: | |
| 260: | |
| 261: | |
| 262: |
|
| 263: | public function getSerial()
|
| 264: | {
|
| 265: | if (empty($this->serial)) {
|
| 266: | $this->serial = sha1(serialize($this->getAll()));
|
| 267: | }
|
| 268: | return $this->serial;
|
| 269: | }
|
| 270: |
|
| 271: | |
| 272: | |
| 273: | |
| 274: | |
| 275: |
|
| 276: | public function getAll()
|
| 277: | {
|
| 278: | if (!$this->finalized) {
|
| 279: | $this->autoFinalize();
|
| 280: | }
|
| 281: | $ret = array();
|
| 282: | foreach ($this->plist->squash() as $name => $value) {
|
| 283: | list($ns, $key) = explode('.', $name, 2);
|
| 284: | $ret[$ns][$key] = $value;
|
| 285: | }
|
| 286: | return $ret;
|
| 287: | }
|
| 288: |
|
| 289: | |
| 290: | |
| 291: | |
| 292: | |
| 293: | |
| 294: | |
| 295: |
|
| 296: | public function set($key, $value, $a = null)
|
| 297: | {
|
| 298: | if (strpos($key, '.') === false) {
|
| 299: | $namespace = $key;
|
| 300: | $directive = $value;
|
| 301: | $value = $a;
|
| 302: | $key = "$key.$directive";
|
| 303: | $this->triggerError("Using deprecated API: use \$config->set('$key', ...) instead", E_USER_NOTICE);
|
| 304: | } else {
|
| 305: | list($namespace) = explode('.', $key);
|
| 306: | }
|
| 307: | if ($this->isFinalized('Cannot set directive after finalization')) {
|
| 308: | return;
|
| 309: | }
|
| 310: | if (!isset($this->def->info[$key])) {
|
| 311: | $this->triggerError(
|
| 312: | 'Cannot set undefined directive ' . htmlspecialchars($key) . ' to value',
|
| 313: | E_USER_WARNING
|
| 314: | );
|
| 315: | return;
|
| 316: | }
|
| 317: | $def = $this->def->info[$key];
|
| 318: |
|
| 319: | if (isset($def->isAlias)) {
|
| 320: | if ($this->aliasMode) {
|
| 321: | $this->triggerError(
|
| 322: | 'Double-aliases not allowed, please fix '.
|
| 323: | 'ConfigSchema bug with' . $key,
|
| 324: | E_USER_ERROR
|
| 325: | );
|
| 326: | return;
|
| 327: | }
|
| 328: | $this->aliasMode = true;
|
| 329: | $this->set($def->key, $value);
|
| 330: | $this->aliasMode = false;
|
| 331: | $this->triggerError("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE);
|
| 332: | return;
|
| 333: | }
|
| 334: |
|
| 335: |
|
| 336: |
|
| 337: | $rtype = is_int($def) ? $def : $def->type;
|
| 338: | if ($rtype < 0) {
|
| 339: | $type = -$rtype;
|
| 340: | $allow_null = true;
|
| 341: | } else {
|
| 342: | $type = $rtype;
|
| 343: | $allow_null = isset($def->allow_null);
|
| 344: | }
|
| 345: |
|
| 346: | try {
|
| 347: | $value = $this->parser->parse($value, $type, $allow_null);
|
| 348: | } catch (HTMLPurifier_VarParserException $e) {
|
| 349: | $this->triggerError(
|
| 350: | 'Value for ' . $key . ' is of invalid type, should be ' .
|
| 351: | HTMLPurifier_VarParser::getTypeName($type),
|
| 352: | E_USER_WARNING
|
| 353: | );
|
| 354: | return;
|
| 355: | }
|
| 356: | if (is_string($value) && is_object($def)) {
|
| 357: |
|
| 358: | if (isset($def->aliases[$value])) {
|
| 359: | $value = $def->aliases[$value];
|
| 360: | }
|
| 361: |
|
| 362: | if (isset($def->allowed) && !isset($def->allowed[$value])) {
|
| 363: | $this->triggerError(
|
| 364: | 'Value not supported, valid values are: ' .
|
| 365: | $this->_listify($def->allowed),
|
| 366: | E_USER_WARNING
|
| 367: | );
|
| 368: | return;
|
| 369: | }
|
| 370: | }
|
| 371: | $this->plist->set($key, $value);
|
| 372: |
|
| 373: |
|
| 374: |
|
| 375: |
|
| 376: | if ($namespace == 'HTML' || $namespace == 'CSS' || $namespace == 'URI') {
|
| 377: | $this->definitions[$namespace] = null;
|
| 378: | }
|
| 379: |
|
| 380: | $this->serials[$namespace] = false;
|
| 381: | }
|
| 382: |
|
| 383: | |
| 384: | |
| 385: | |
| 386: | |
| 387: | |
| 388: | |
| 389: |
|
| 390: | private function _listify($lookup)
|
| 391: | {
|
| 392: | $list = array();
|
| 393: | foreach ($lookup as $name => $b) {
|
| 394: | $list[] = $name;
|
| 395: | }
|
| 396: | return implode(', ', $list);
|
| 397: | }
|
| 398: |
|
| 399: | |
| 400: | |
| 401: | |
| 402: | |
| 403: | |
| 404: | |
| 405: | |
| 406: | |
| 407: | |
| 408: | |
| 409: | |
| 410: | |
| 411: | |
| 412: |
|
| 413: | public function getHTMLDefinition($raw = false, $optimized = false)
|
| 414: | {
|
| 415: | return $this->getDefinition('HTML', $raw, $optimized);
|
| 416: | }
|
| 417: |
|
| 418: | |
| 419: | |
| 420: | |
| 421: | |
| 422: | |
| 423: | |
| 424: | |
| 425: | |
| 426: | |
| 427: | |
| 428: | |
| 429: | |
| 430: | |
| 431: |
|
| 432: | public function getCSSDefinition($raw = false, $optimized = false)
|
| 433: | {
|
| 434: | return $this->getDefinition('CSS', $raw, $optimized);
|
| 435: | }
|
| 436: |
|
| 437: | |
| 438: | |
| 439: | |
| 440: | |
| 441: | |
| 442: | |
| 443: | |
| 444: | |
| 445: | |
| 446: | |
| 447: | |
| 448: | |
| 449: | |
| 450: |
|
| 451: | public function getURIDefinition($raw = false, $optimized = false)
|
| 452: | {
|
| 453: | return $this->getDefinition('URI', $raw, $optimized);
|
| 454: | }
|
| 455: |
|
| 456: | |
| 457: | |
| 458: | |
| 459: | |
| 460: | |
| 461: | |
| 462: | |
| 463: | |
| 464: | |
| 465: | |
| 466: | |
| 467: | |
| 468: | |
| 469: | |
| 470: | |
| 471: | |
| 472: |
|
| 473: | public function getDefinition($type, $raw = false, $optimized = false)
|
| 474: | {
|
| 475: | if ($optimized && !$raw) {
|
| 476: | throw new HTMLPurifier_Exception("Cannot set optimized = true when raw = false");
|
| 477: | }
|
| 478: | if (!$this->finalized) {
|
| 479: | $this->autoFinalize();
|
| 480: | }
|
| 481: |
|
| 482: | $lock = $this->lock;
|
| 483: | $this->lock = null;
|
| 484: | $factory = HTMLPurifier_DefinitionCacheFactory::instance();
|
| 485: | $cache = $factory->create($type, $this);
|
| 486: | $this->lock = $lock;
|
| 487: | if (!$raw) {
|
| 488: |
|
| 489: |
|
| 490: |
|
| 491: | if (!empty($this->definitions[$type])) {
|
| 492: | $def = $this->definitions[$type];
|
| 493: |
|
| 494: | if ($def->setup) {
|
| 495: | return $def;
|
| 496: | } else {
|
| 497: | $def->setup($this);
|
| 498: | if ($def->optimized) {
|
| 499: | $cache->add($def, $this);
|
| 500: | }
|
| 501: | return $def;
|
| 502: | }
|
| 503: | }
|
| 504: |
|
| 505: | $def = $cache->get($this);
|
| 506: | if ($def) {
|
| 507: |
|
| 508: | $this->definitions[$type] = $def;
|
| 509: | return $def;
|
| 510: | }
|
| 511: |
|
| 512: | $def = $this->initDefinition($type);
|
| 513: |
|
| 514: | $this->lock = $type;
|
| 515: | $def->setup($this);
|
| 516: | $this->lock = null;
|
| 517: |
|
| 518: | $cache->add($def, $this);
|
| 519: |
|
| 520: | return $def;
|
| 521: | } else {
|
| 522: |
|
| 523: |
|
| 524: |
|
| 525: | $def = null;
|
| 526: | if ($optimized) {
|
| 527: | if (is_null($this->get($type . '.DefinitionID'))) {
|
| 528: |
|
| 529: | throw new HTMLPurifier_Exception(
|
| 530: | "Cannot retrieve raw version without specifying %$type.DefinitionID"
|
| 531: | );
|
| 532: | }
|
| 533: | }
|
| 534: | if (!empty($this->definitions[$type])) {
|
| 535: | $def = $this->definitions[$type];
|
| 536: | if ($def->setup && !$optimized) {
|
| 537: | $extra = $this->chatty ?
|
| 538: | " (try moving this code block earlier in your initialization)" :
|
| 539: | "";
|
| 540: | throw new HTMLPurifier_Exception(
|
| 541: | "Cannot retrieve raw definition after it has already been setup" .
|
| 542: | $extra
|
| 543: | );
|
| 544: | }
|
| 545: | if ($def->optimized === null) {
|
| 546: | $extra = $this->chatty ? " (try flushing your cache)" : "";
|
| 547: | throw new HTMLPurifier_Exception(
|
| 548: | "Optimization status of definition is unknown" . $extra
|
| 549: | );
|
| 550: | }
|
| 551: | if ($def->optimized !== $optimized) {
|
| 552: | $msg = $optimized ? "optimized" : "unoptimized";
|
| 553: | $extra = $this->chatty ?
|
| 554: | " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)"
|
| 555: | : "";
|
| 556: | throw new HTMLPurifier_Exception(
|
| 557: | "Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra
|
| 558: | );
|
| 559: | }
|
| 560: | }
|
| 561: |
|
| 562: | if ($def) {
|
| 563: | if ($def->setup) {
|
| 564: |
|
| 565: | return null;
|
| 566: | } else {
|
| 567: | return $def;
|
| 568: | }
|
| 569: | }
|
| 570: |
|
| 571: |
|
| 572: |
|
| 573: |
|
| 574: |
|
| 575: | if ($optimized) {
|
| 576: |
|
| 577: |
|
| 578: |
|
| 579: | $def = $cache->get($this);
|
| 580: | if ($def) {
|
| 581: |
|
| 582: |
|
| 583: | $this->definitions[$type] = $def;
|
| 584: | return null;
|
| 585: | }
|
| 586: | }
|
| 587: |
|
| 588: | if (!$optimized) {
|
| 589: | if (!is_null($this->get($type . '.DefinitionID'))) {
|
| 590: | if ($this->chatty) {
|
| 591: | $this->triggerError(
|
| 592: | 'Due to a documentation error in previous version of HTML Purifier, your ' .
|
| 593: | 'definitions are not being cached. If this is OK, you can remove the ' .
|
| 594: | '%$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, ' .
|
| 595: | 'modify your code to use maybeGetRawDefinition, and test if the returned ' .
|
| 596: | 'value is null before making any edits (if it is null, that means that a ' .
|
| 597: | 'cached version is available, and no raw operations are necessary). See ' .
|
| 598: | '<a href="http://htmlpurifier.org/docs/enduser-customize.html#optimized">' .
|
| 599: | 'Customize</a> for more details',
|
| 600: | E_USER_WARNING
|
| 601: | );
|
| 602: | } else {
|
| 603: | $this->triggerError(
|
| 604: | "Useless DefinitionID declaration",
|
| 605: | E_USER_WARNING
|
| 606: | );
|
| 607: | }
|
| 608: | }
|
| 609: | }
|
| 610: |
|
| 611: | $def = $this->initDefinition($type);
|
| 612: | $def->optimized = $optimized;
|
| 613: | return $def;
|
| 614: | }
|
| 615: | throw new HTMLPurifier_Exception("The impossible happened!");
|
| 616: | }
|
| 617: |
|
| 618: | |
| 619: | |
| 620: | |
| 621: | |
| 622: | |
| 623: | |
| 624: | |
| 625: |
|
| 626: | private function initDefinition($type)
|
| 627: | {
|
| 628: |
|
| 629: | if ($type == 'HTML') {
|
| 630: | $def = new HTMLPurifier_HTMLDefinition();
|
| 631: | } elseif ($type == 'CSS') {
|
| 632: | $def = new HTMLPurifier_CSSDefinition();
|
| 633: | } elseif ($type == 'URI') {
|
| 634: | $def = new HTMLPurifier_URIDefinition();
|
| 635: | } else {
|
| 636: | throw new HTMLPurifier_Exception(
|
| 637: | "Definition of $type type not supported"
|
| 638: | );
|
| 639: | }
|
| 640: | $this->definitions[$type] = $def;
|
| 641: | return $def;
|
| 642: | }
|
| 643: |
|
| 644: | public function maybeGetRawDefinition($name)
|
| 645: | {
|
| 646: | return $this->getDefinition($name, true, true);
|
| 647: | }
|
| 648: |
|
| 649: | |
| 650: | |
| 651: |
|
| 652: | public function maybeGetRawHTMLDefinition()
|
| 653: | {
|
| 654: | return $this->getDefinition('HTML', true, true);
|
| 655: | }
|
| 656: |
|
| 657: | |
| 658: | |
| 659: |
|
| 660: | public function maybeGetRawCSSDefinition()
|
| 661: | {
|
| 662: | return $this->getDefinition('CSS', true, true);
|
| 663: | }
|
| 664: |
|
| 665: | |
| 666: | |
| 667: |
|
| 668: | public function maybeGetRawURIDefinition()
|
| 669: | {
|
| 670: | return $this->getDefinition('URI', true, true);
|
| 671: | }
|
| 672: |
|
| 673: | |
| 674: | |
| 675: | |
| 676: | |
| 677: | |
| 678: |
|
| 679: | public function loadArray($config_array)
|
| 680: | {
|
| 681: | if ($this->isFinalized('Cannot load directives after finalization')) {
|
| 682: | return;
|
| 683: | }
|
| 684: | foreach ($config_array as $key => $value) {
|
| 685: | $key = str_replace('_', '.', $key);
|
| 686: | if (strpos($key, '.') !== false) {
|
| 687: | $this->set($key, $value);
|
| 688: | } else {
|
| 689: | $namespace = $key;
|
| 690: | $namespace_values = $value;
|
| 691: | foreach ($namespace_values as $directive => $value2) {
|
| 692: | $this->set($namespace .'.'. $directive, $value2);
|
| 693: | }
|
| 694: | }
|
| 695: | }
|
| 696: | }
|
| 697: |
|
| 698: | |
| 699: | |
| 700: | |
| 701: | |
| 702: | |
| 703: | |
| 704: | |
| 705: | |
| 706: | |
| 707: |
|
| 708: | public static function getAllowedDirectivesForForm($allowed, $schema = null)
|
| 709: | {
|
| 710: | if (!$schema) {
|
| 711: | $schema = HTMLPurifier_ConfigSchema::instance();
|
| 712: | }
|
| 713: | if ($allowed !== true) {
|
| 714: | if (is_string($allowed)) {
|
| 715: | $allowed = array($allowed);
|
| 716: | }
|
| 717: | $allowed_ns = array();
|
| 718: | $allowed_directives = array();
|
| 719: | $blacklisted_directives = array();
|
| 720: | foreach ($allowed as $ns_or_directive) {
|
| 721: | if (strpos($ns_or_directive, '.') !== false) {
|
| 722: |
|
| 723: | if ($ns_or_directive[0] == '-') {
|
| 724: | $blacklisted_directives[substr($ns_or_directive, 1)] = true;
|
| 725: | } else {
|
| 726: | $allowed_directives[$ns_or_directive] = true;
|
| 727: | }
|
| 728: | } else {
|
| 729: |
|
| 730: | $allowed_ns[$ns_or_directive] = true;
|
| 731: | }
|
| 732: | }
|
| 733: | }
|
| 734: | $ret = array();
|
| 735: | foreach ($schema->info as $key => $def) {
|
| 736: | list($ns, $directive) = explode('.', $key, 2);
|
| 737: | if ($allowed !== true) {
|
| 738: | if (isset($blacklisted_directives["$ns.$directive"])) {
|
| 739: | continue;
|
| 740: | }
|
| 741: | if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) {
|
| 742: | continue;
|
| 743: | }
|
| 744: | }
|
| 745: | if (isset($def->isAlias)) {
|
| 746: | continue;
|
| 747: | }
|
| 748: | if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') {
|
| 749: | continue;
|
| 750: | }
|
| 751: | $ret[] = array($ns, $directive);
|
| 752: | }
|
| 753: | return $ret;
|
| 754: | }
|
| 755: |
|
| 756: | |
| 757: | |
| 758: | |
| 759: | |
| 760: | |
| 761: | |
| 762: | |
| 763: | |
| 764: | |
| 765: | |
| 766: | |
| 767: |
|
| 768: | public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null)
|
| 769: | {
|
| 770: | $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema);
|
| 771: | $config = HTMLPurifier_Config::create($ret, $schema);
|
| 772: | return $config;
|
| 773: | }
|
| 774: |
|
| 775: | |
| 776: | |
| 777: | |
| 778: | |
| 779: | |
| 780: | |
| 781: | |
| 782: |
|
| 783: | public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true)
|
| 784: | {
|
| 785: | $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def);
|
| 786: | $this->loadArray($ret);
|
| 787: | }
|
| 788: |
|
| 789: | |
| 790: | |
| 791: | |
| 792: | |
| 793: | |
| 794: | |
| 795: | |
| 796: | |
| 797: | |
| 798: | |
| 799: | |
| 800: |
|
| 801: | public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null)
|
| 802: | {
|
| 803: | if ($index !== false) {
|
| 804: | $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
|
| 805: | }
|
| 806: | $mq = $mq_fix && version_compare(PHP_VERSION, '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc();
|
| 807: |
|
| 808: | $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema);
|
| 809: | $ret = array();
|
| 810: | foreach ($allowed as $key) {
|
| 811: | list($ns, $directive) = $key;
|
| 812: | $skey = "$ns.$directive";
|
| 813: | if (!empty($array["Null_$skey"])) {
|
| 814: | $ret[$ns][$directive] = null;
|
| 815: | continue;
|
| 816: | }
|
| 817: | if (!isset($array[$skey])) {
|
| 818: | continue;
|
| 819: | }
|
| 820: | $value = $mq ? stripslashes($array[$skey]) : $array[$skey];
|
| 821: | $ret[$ns][$directive] = $value;
|
| 822: | }
|
| 823: | return $ret;
|
| 824: | }
|
| 825: |
|
| 826: | |
| 827: | |
| 828: | |
| 829: | |
| 830: |
|
| 831: | public function loadIni($filename)
|
| 832: | {
|
| 833: | if ($this->isFinalized('Cannot load directives after finalization')) {
|
| 834: | return;
|
| 835: | }
|
| 836: | $array = parse_ini_file($filename, true);
|
| 837: | $this->loadArray($array);
|
| 838: | }
|
| 839: |
|
| 840: | |
| 841: | |
| 842: | |
| 843: | |
| 844: | |
| 845: | |
| 846: |
|
| 847: | public function isFinalized($error = false)
|
| 848: | {
|
| 849: | if ($this->finalized && $error) {
|
| 850: | $this->triggerError($error, E_USER_ERROR);
|
| 851: | }
|
| 852: | return $this->finalized;
|
| 853: | }
|
| 854: |
|
| 855: | |
| 856: | |
| 857: | |
| 858: |
|
| 859: | public function autoFinalize()
|
| 860: | {
|
| 861: | if ($this->autoFinalize) {
|
| 862: | $this->finalize();
|
| 863: | } else {
|
| 864: | $this->plist->squash(true);
|
| 865: | }
|
| 866: | }
|
| 867: |
|
| 868: | |
| 869: | |
| 870: |
|
| 871: | public function finalize()
|
| 872: | {
|
| 873: | $this->finalized = true;
|
| 874: | $this->parser = null;
|
| 875: | }
|
| 876: |
|
| 877: | |
| 878: | |
| 879: | |
| 880: | |
| 881: | |
| 882: | |
| 883: |
|
| 884: | protected function triggerError($msg, $no)
|
| 885: | {
|
| 886: |
|
| 887: | $extra = '';
|
| 888: | if ($this->chatty) {
|
| 889: | $trace = debug_backtrace();
|
| 890: |
|
| 891: | for ($i = 0, $c = count($trace); $i < $c - 1; $i++) {
|
| 892: |
|
| 893: | if (isset($trace[$i + 1]['class']) && $trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
|
| 894: | continue;
|
| 895: | }
|
| 896: | $frame = $trace[$i];
|
| 897: | $extra = " invoked on line {$frame['line']} in file {$frame['file']}";
|
| 898: | break;
|
| 899: | }
|
| 900: | }
|
| 901: | trigger_error($msg . $extra, $no);
|
| 902: | }
|
| 903: |
|
| 904: | |
| 905: | |
| 906: | |
| 907: | |
| 908: | |
| 909: |
|
| 910: | public function serialize()
|
| 911: | {
|
| 912: | $this->getDefinition('HTML');
|
| 913: | $this->getDefinition('CSS');
|
| 914: | $this->getDefinition('URI');
|
| 915: | return serialize($this);
|
| 916: | }
|
| 917: |
|
| 918: | }
|
| 919: |
|
| 920: |
|
| 921: | |