49         $definition = 
$config->getHTMLDefinition();
 
   53         $escape_invalid_tags = 
$config->get(
'Core.EscapeInvalidTags');
 
   55         $global_parent_allowed_elements = array();
 
   56         if (isset($definition->info[$definition->info_parent])) {
 
   58             $global_parent_allowed_elements = $definition->info[$definition->info_parent]->child->getAllowedElements(
$config);
 
   60         $e = 
$context->get(
'ErrorCollector', 
true);
 
   78         $context->register(
'CurrentToken',   $token);
 
   82         $this->injectors = array();
 
   85         $def_injectors = $definition->info_injector;
 
   90             if (strpos($injector, 
'.') !== 
false) 
continue;
 
   91             $injector = 
"HTMLPurifier_Injector_$injector";
 
   93             $this->injectors[] = 
new $injector;
 
   95         foreach ($def_injectors as $injector) {
 
   97             $this->injectors[] = $injector;
 
   99         foreach ($custom_injectors as $injector) {
 
  100             if (!$injector) 
continue;
 
  101             if (is_string($injector)) {
 
  102                 $injector = 
"HTMLPurifier_Injector_$injector";
 
  103                 $injector = 
new $injector;
 
  105             $this->injectors[] = $injector;
 
  110         foreach ($this->injectors as $ix => $injector) {
 
  112             if (!$error) 
continue;
 
  113             array_splice($this->injectors, $ix, 1); 
 
  114             trigger_error(
"Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING);
 
  132             $reprocess ? $reprocess = 
false : 
$t++
 
  136             if (is_int($i) && $i >= 0) {
 
  140                 $rewind_to = $this->injectors[$i]->getRewind();
 
  141                 if (is_int($rewind_to) && $rewind_to < 
$t) {
 
  142                     if ($rewind_to < 0) $rewind_to = 0;
 
  143                     while (
$t > $rewind_to) {
 
  148                         unset($prev->skip[$i]);
 
  160                 if (empty($this->stack)) 
break;
 
  163                 $top_nesting = array_pop($this->stack);
 
  164                 $this->stack[] = $top_nesting;
 
  167                 if ($e && !isset($top_nesting->armor[
'MakeWellFormed_TagClosedError'])) {
 
  168                     $e->send(E_NOTICE, 
'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting);
 
  185             if (empty($token->is_tag)) {
 
  187                     foreach ($this->injectors as $i => $injector) {
 
  188                         if (isset($token->skip[$i])) 
continue;
 
  189                         if ($token->rewind !== null && $token->rewind !== $i) 
continue;
 
  190                         $injector->handleText($token);
 
  200             if (isset($definition->info[$token->name])) {
 
  201                 $type = $definition->info[$token->name]->child->type;
 
  215                 $this->
insertBefore(
new HTMLPurifier_Token_Start($token->name, $token->attr, $token->line, $token->col, $token->armor));
 
  219             } elseif ($token instanceof HTMLPurifier_Token_Empty) {
 
  222             } elseif ($token instanceof HTMLPurifier_Token_Start) {
 
  226                 if (!empty($this->stack)) {
 
  241                     $parent = array_pop($this->stack);
 
  242                     $this->stack[] = $parent;
 
  244                     if (isset($definition->info[$parent->name])) {
 
  245                         $elements = $definition->info[$parent->name]->child->getAllowedElements(
$config);
 
  246                         $autoclose = !isset($elements[$token->name]);
 
  251                     if ($autoclose && $definition->info[$token->name]->wrap) {
 
  255                         $wrapname = $definition->info[$token->name]->wrap;
 
  256                         $wrapdef = $definition->info[$wrapname];
 
  257                         $elements = $wrapdef->child->getAllowedElements(
$config);
 
  258                         $parent_elements = $definition->info[$parent->name]->child->getAllowedElements(
$config);
 
  259                         if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) {
 
  260                             $newtoken = 
new HTMLPurifier_Token_Start($wrapname);
 
  268                     if ($autoclose && $definition->info[$parent->name]->formatting) {
 
  275                         $autoclose_ok = isset($global_parent_allowed_elements[$token->name]);
 
  276                         if (!$autoclose_ok) {
 
  277                             foreach ($this->stack as $ancestor) {
 
  278                                 $elements = $definition->info[$ancestor->name]->child->getAllowedElements(
$config);
 
  279                                 if (isset($elements[$token->name])) {
 
  280                                     $autoclose_ok = 
true;
 
  283                                 if ($definition->info[$token->name]->wrap) {
 
  284                                     $wrapname = $definition->info[$token->name]->wrap;
 
  285                                     $wrapdef = $definition->info[$wrapname];
 
  286                                     $wrap_elements = $wrapdef->child->getAllowedElements(
$config);
 
  287                                     if (isset($wrap_elements[$token->name]) && isset($elements[$wrapname])) {
 
  288                                         $autoclose_ok = 
true;
 
  297                             $new_token->start = $parent;
 
  299                                 $element = clone $parent;
 
  301                                 $element->armor[
'MakeWellFormed_TagClosedError'] = 
true;
 
  302                                 $element->carryover = 
true;
 
  303                                 $this->
processToken(array($new_token, $token, $element));
 
  308                             if ($e && !isset($parent->armor[
'MakeWellFormed_TagClosedError'])) {
 
  310                                     $e->send(E_NOTICE, 
'Strategy_MakeWellFormed: Tag auto closed', $parent);
 
  312                                     $e->send(E_NOTICE, 
'Strategy_MakeWellFormed: Tag carryover', $parent);
 
  327                 foreach ($this->injectors as $i => $injector) {
 
  328                     if (isset($token->skip[$i])) 
continue;
 
  329                     if ($token->rewind !== null && $token->rewind !== $i) 
continue;
 
  330                     $injector->handleElement($token);
 
  338                     if ($token instanceof HTMLPurifier_Token_Start) {
 
  339                         $this->stack[] = $token;
 
  341                         throw new HTMLPurifier_Exception(
'Improper handling of end tag in start code; possible error in MakeWellFormed');
 
  353             if (empty($this->stack)) {
 
  354                 if ($escape_invalid_tags) {
 
  355                     if ($e) $e->send(E_WARNING, 
'Strategy_MakeWellFormed: Unnecessary end tag to text');
 
  357                         $generator->generateFromToken($token)
 
  361                     if ($e) $e->send(E_WARNING, 
'Strategy_MakeWellFormed: Unnecessary end tag removed');
 
  371             $current_parent = array_pop($this->stack);
 
  372             if ($current_parent->name == $token->name) {
 
  373                 $token->start = $current_parent;
 
  374                 foreach ($this->injectors as $i => $injector) {
 
  375                     if (isset($token->skip[$i])) 
continue;
 
  376                     if ($token->rewind !== null && $token->rewind !== $i) 
continue;
 
  377                     $injector->handleEnd($token);
 
  379                     $this->stack[] = $current_parent;
 
  389             $this->stack[] = $current_parent;
 
  393             $size = count($this->stack);
 
  395             $skipped_tags = 
false;
 
  396             for ($j = 
$size - 2; $j >= 0; $j--) {
 
  397                 if ($this->stack[$j]->name == $token->name) {
 
  398                     $skipped_tags = array_slice($this->stack, $j);
 
  404             if ($skipped_tags === 
false) {
 
  405                 if ($escape_invalid_tags) {
 
  407                         $generator->generateFromToken($token)
 
  409                     if ($e) $e->send(E_WARNING, 
'Strategy_MakeWellFormed: Stray end tag to text');
 
  412                     if ($e) $e->send(E_WARNING, 
'Strategy_MakeWellFormed: Stray end tag removed');
 
  419             $c = count($skipped_tags);
 
  421                 for ($j = $c - 1; $j > 0; $j--) {
 
  424                     if (!isset($skipped_tags[$j]->armor[
'MakeWellFormed_TagClosedError'])) {
 
  425                         $e->send(E_NOTICE, 
'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]);
 
  431             $replace = array($token);
 
  432             for ($j = 1; $j < $c; $j++) {
 
  434                 $new_token = 
new HTMLPurifier_Token_End($skipped_tags[$j]->name);
 
  435                 $new_token->start = $skipped_tags[$j];
 
  436                 array_unshift($replace, $new_token);
 
  437                 if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) {
 
  439                     $element = clone $skipped_tags[$j];
 
  440                     $element->carryover = 
true;
 
  441                     $element->armor[
'MakeWellFormed_TagClosedError'] = 
true;
 
  442                     $replace[] = $element;
 
  450         $context->destroy(
'CurrentNesting');
 
  455         unset($this->injectors, $this->stack, $this->tokens, $this->t);
 
  482         if (is_object($token)) $token = array(1, $token);
 
  483         if (is_int($token))    $token = array($token);
 
  484         if ($token === 
false)  $token = array(1);
 
  486         if (!is_int($token[0])) array_unshift($token, 1);
 
  492         $delete = array_shift($token);
 
  493         $old = array_splice($this->tokens, $this->t, $delete, $token);
 
  495         if ($injector > -1) {
 
  497             $oldskip = isset($old[0]) ? $old[0]->skip : array();
 
  498             foreach ($token as $object) {
 
  499                 $object->skip = $oldskip;
 
  500                 $object->skip[$injector] = 
true;
 
  511         array_splice($this->tokens, $this->t, 0, array($token));
 
  518     private function remove() {
 
  519         array_splice($this->tokens, $this->t, 1);
 
  526     private function swap($token) {