GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — develop (#1814)
by
unknown
11:57
created
classes/security/htmlpurifier/library/HTMLPurifier/PropertyList.php 2 patches
Indentation   +66 added lines, -66 removed lines patch added patch discarded remove patch
@@ -5,82 +5,82 @@
 block discarded – undo
5 5
  */
6 6
 class HTMLPurifier_PropertyList
7 7
 {
8
-    /**
9
-     * Internal data-structure for properties
10
-     */
11
-    protected $data = array();
8
+	/**
9
+	 * Internal data-structure for properties
10
+	 */
11
+	protected $data = array();
12 12
 
13
-    /**
14
-     * Parent plist
15
-     */
16
-    protected $parent;
13
+	/**
14
+	 * Parent plist
15
+	 */
16
+	protected $parent;
17 17
 
18
-    protected $cache;
18
+	protected $cache;
19 19
 
20
-    public function __construct($parent = null) {
21
-        $this->parent = $parent;
22
-    }
20
+	public function __construct($parent = null) {
21
+		$this->parent = $parent;
22
+	}
23 23
 
24
-    /**
25
-     * Recursively retrieves the value for a key
26
-     */
27
-    public function get($name) {
28
-        if ($this->has($name)) return $this->data[$name];
29
-        // possible performance bottleneck, convert to iterative if necessary
30
-        if ($this->parent) return $this->parent->get($name);
31
-        throw new HTMLPurifier_Exception("Key '$name' not found");
32
-    }
24
+	/**
25
+	 * Recursively retrieves the value for a key
26
+	 */
27
+	public function get($name) {
28
+		if ($this->has($name)) return $this->data[$name];
29
+		// possible performance bottleneck, convert to iterative if necessary
30
+		if ($this->parent) return $this->parent->get($name);
31
+		throw new HTMLPurifier_Exception("Key '$name' not found");
32
+	}
33 33
 
34
-    /**
35
-     * Sets the value of a key, for this plist
36
-     */
37
-    public function set($name, $value) {
38
-        $this->data[$name] = $value;
39
-    }
34
+	/**
35
+	 * Sets the value of a key, for this plist
36
+	 */
37
+	public function set($name, $value) {
38
+		$this->data[$name] = $value;
39
+	}
40 40
 
41
-    /**
42
-     * Returns true if a given key exists
43
-     */
44
-    public function has($name) {
45
-        return array_key_exists($name, $this->data);
46
-    }
41
+	/**
42
+	 * Returns true if a given key exists
43
+	 */
44
+	public function has($name) {
45
+		return array_key_exists($name, $this->data);
46
+	}
47 47
 
48
-    /**
49
-     * Resets a value to the value of it's parent, usually the default. If
50
-     * no value is specified, the entire plist is reset.
51
-     */
52
-    public function reset($name = null) {
53
-        if ($name == null) $this->data = array();
54
-        else unset($this->data[$name]);
55
-    }
48
+	/**
49
+	 * Resets a value to the value of it's parent, usually the default. If
50
+	 * no value is specified, the entire plist is reset.
51
+	 */
52
+	public function reset($name = null) {
53
+		if ($name == null) $this->data = array();
54
+		else unset($this->data[$name]);
55
+	}
56 56
 
57
-    /**
58
-     * Squashes this property list and all of its property lists into a single
59
-     * array, and returns the array. This value is cached by default.
60
-     * @param $force If true, ignores the cache and regenerates the array.
61
-     */
62
-    public function squash($force = false) {
63
-        if ($this->cache !== null && !$force) return $this->cache;
64
-        if ($this->parent) {
65
-            return $this->cache = array_merge($this->parent->squash($force), $this->data);
66
-        } else {
67
-            return $this->cache = $this->data;
68
-        }
69
-    }
57
+	/**
58
+	 * Squashes this property list and all of its property lists into a single
59
+	 * array, and returns the array. This value is cached by default.
60
+	 * @param $force If true, ignores the cache and regenerates the array.
61
+	 */
62
+	public function squash($force = false) {
63
+		if ($this->cache !== null && !$force) return $this->cache;
64
+		if ($this->parent) {
65
+			return $this->cache = array_merge($this->parent->squash($force), $this->data);
66
+		} else {
67
+			return $this->cache = $this->data;
68
+		}
69
+	}
70 70
 
71
-    /**
72
-     * Returns the parent plist.
73
-     */
74
-    public function getParent() {
75
-        return $this->parent;
76
-    }
71
+	/**
72
+	 * Returns the parent plist.
73
+	 */
74
+	public function getParent() {
75
+		return $this->parent;
76
+	}
77 77
 
78
-    /**
79
-     * Sets the parent plist.
80
-     */
81
-    public function setParent($plist) {
82
-        $this->parent = $plist;
83
-    }
78
+	/**
79
+	 * Sets the parent plist.
80
+	 */
81
+	public function setParent($plist) {
82
+		$this->parent = $plist;
83
+	}
84 84
 }
85 85
 
86 86
 // vim: et sw=4 sts=4
Please login to merge, or discard this patch.
Braces   +14 added lines, -5 removed lines patch added patch discarded remove patch
@@ -25,9 +25,13 @@  discard block
 block discarded – undo
25 25
      * Recursively retrieves the value for a key
26 26
      */
27 27
     public function get($name) {
28
-        if ($this->has($name)) return $this->data[$name];
28
+        if ($this->has($name)) {
29
+        	return $this->data[$name];
30
+        }
29 31
         // possible performance bottleneck, convert to iterative if necessary
30
-        if ($this->parent) return $this->parent->get($name);
32
+        if ($this->parent) {
33
+        	return $this->parent->get($name);
34
+        }
31 35
         throw new HTMLPurifier_Exception("Key '$name' not found");
32 36
     }
33 37
 
@@ -50,8 +54,11 @@  discard block
 block discarded – undo
50 54
      * no value is specified, the entire plist is reset.
51 55
      */
52 56
     public function reset($name = null) {
53
-        if ($name == null) $this->data = array();
54
-        else unset($this->data[$name]);
57
+        if ($name == null) {
58
+        	$this->data = array();
59
+        } else {
60
+        	unset($this->data[$name]);
61
+        }
55 62
     }
56 63
 
57 64
     /**
@@ -60,7 +67,9 @@  discard block
 block discarded – undo
60 67
      * @param $force If true, ignores the cache and regenerates the array.
61 68
      */
62 69
     public function squash($force = false) {
63
-        if ($this->cache !== null && !$force) return $this->cache;
70
+        if ($this->cache !== null && !$force) {
71
+        	return $this->cache;
72
+        }
64 73
         if ($this->parent) {
65 74
             return $this->cache = array_merge($this->parent->squash($force), $this->data);
66 75
         } else {
Please login to merge, or discard this patch.
classes/security/htmlpurifier/library/HTMLPurifier/PropertyListIterator.php 2 patches
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -6,26 +6,26 @@
 block discarded – undo
6 6
 class HTMLPurifier_PropertyListIterator extends FilterIterator
7 7
 {
8 8
 
9
-    protected $l;
10
-    protected $filter;
9
+	protected $l;
10
+	protected $filter;
11 11
 
12
-    /**
13
-     * @param $data Array of data to iterate over
14
-     * @param $filter Optional prefix to only allow values of
15
-     */
16
-    public function __construct(Iterator $iterator, $filter = null) {
17
-        parent::__construct($iterator);
18
-        $this->l = strlen($filter);
19
-        $this->filter = $filter;
20
-    }
12
+	/**
13
+	 * @param $data Array of data to iterate over
14
+	 * @param $filter Optional prefix to only allow values of
15
+	 */
16
+	public function __construct(Iterator $iterator, $filter = null) {
17
+		parent::__construct($iterator);
18
+		$this->l = strlen($filter);
19
+		$this->filter = $filter;
20
+	}
21 21
 
22
-    public function accept() {
23
-        $key = $this->getInnerIterator()->key();
24
-        if( strncmp($key, $this->filter, $this->l) !== 0 ) {
25
-            return false;
26
-        }
27
-        return true;
28
-    }
22
+	public function accept() {
23
+		$key = $this->getInnerIterator()->key();
24
+		if( strncmp($key, $this->filter, $this->l) !== 0 ) {
25
+			return false;
26
+		}
27
+		return true;
28
+	}
29 29
 
30 30
 }
31 31
 
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -21,7 +21,7 @@
 block discarded – undo
21 21
 
22 22
     public function accept() {
23 23
         $key = $this->getInnerIterator()->key();
24
-        if( strncmp($key, $this->filter, $this->l) !== 0 ) {
24
+        if (strncmp($key, $this->filter, $this->l) !== 0) {
25 25
             return false;
26 26
         }
27 27
         return true;
Please login to merge, or discard this patch.
classes/security/htmlpurifier/library/HTMLPurifier/Strategy.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -12,14 +12,14 @@
 block discarded – undo
12 12
 abstract class HTMLPurifier_Strategy
13 13
 {
14 14
 
15
-    /**
16
-     * Executes the strategy on the tokens.
17
-     *
18
-     * @param $tokens Array of HTMLPurifier_Token objects to be operated on.
19
-     * @param $config Configuration options
20
-     * @returns Processed array of token objects.
21
-     */
22
-    abstract public function execute($tokens, $config, $context);
15
+	/**
16
+	 * Executes the strategy on the tokens.
17
+	 *
18
+	 * @param $tokens Array of HTMLPurifier_Token objects to be operated on.
19
+	 * @param $config Configuration options
20
+	 * @returns Processed array of token objects.
21
+	 */
22
+	abstract public function execute($tokens, $config, $context);
23 23
 
24 24
 }
25 25
 
Please login to merge, or discard this patch.
classes/security/htmlpurifier/library/HTMLPurifier/Strategy/Composite.php 1 patch
Indentation   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -6,17 +6,17 @@
 block discarded – undo
6 6
 abstract class HTMLPurifier_Strategy_Composite extends HTMLPurifier_Strategy
7 7
 {
8 8
 
9
-    /**
10
-     * List of strategies to run tokens through.
11
-     */
12
-    protected $strategies = array();
9
+	/**
10
+	 * List of strategies to run tokens through.
11
+	 */
12
+	protected $strategies = array();
13 13
 
14
-    public function execute($tokens, $config, $context) {
15
-        foreach ($this->strategies as $strategy) {
16
-            $tokens = $strategy->execute($tokens, $config, $context);
17
-        }
18
-        return $tokens;
19
-    }
14
+	public function execute($tokens, $config, $context) {
15
+		foreach ($this->strategies as $strategy) {
16
+			$tokens = $strategy->execute($tokens, $config, $context);
17
+		}
18
+		return $tokens;
19
+	}
20 20
 
21 21
 }
22 22
 
Please login to merge, or discard this patch.
classes/security/htmlpurifier/library/HTMLPurifier/Strategy/Core.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -6,12 +6,12 @@
 block discarded – undo
6 6
 class HTMLPurifier_Strategy_Core extends HTMLPurifier_Strategy_Composite
7 7
 {
8 8
 
9
-    public function __construct() {
10
-        $this->strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements();
11
-        $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed();
12
-        $this->strategies[] = new HTMLPurifier_Strategy_FixNesting();
13
-        $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes();
14
-    }
9
+	public function __construct() {
10
+		$this->strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements();
11
+		$this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed();
12
+		$this->strategies[] = new HTMLPurifier_Strategy_FixNesting();
13
+		$this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes();
14
+	}
15 15
 
16 16
 }
17 17
 
Please login to merge, or discard this patch.
classes/security/htmlpurifier/library/HTMLPurifier/Strategy/FixNesting.php 3 patches
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -31,297 +31,297 @@
 block discarded – undo
31 31
 class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
32 32
 {
33 33
 
34
-    public function execute($tokens, $config, $context) {
35
-        //####################################################################//
36
-        // Pre-processing
37
-
38
-        // get a copy of the HTML definition
39
-        $definition = $config->getHTMLDefinition();
40
-
41
-        // insert implicit "parent" node, will be removed at end.
42
-        // DEFINITION CALL
43
-        $parent_name = $definition->info_parent;
44
-        array_unshift($tokens, new HTMLPurifier_Token_Start($parent_name));
45
-        $tokens[] = new HTMLPurifier_Token_End($parent_name);
46
-
47
-        // setup the context variable 'IsInline', for chameleon processing
48
-        // is 'false' when we are not inline, 'true' when it must always
49
-        // be inline, and an integer when it is inline for a certain
50
-        // branch of the document tree
51
-        $is_inline = $definition->info_parent_def->descendants_are_inline;
52
-        $context->register('IsInline', $is_inline);
53
-
54
-        // setup error collector
55
-        $e =& $context->get('ErrorCollector', true);
56
-
57
-        //####################################################################//
58
-        // Loop initialization
59
-
60
-        // stack that contains the indexes of all parents,
61
-        // $stack[count($stack)-1] being the current parent
62
-        $stack = array();
63
-
64
-        // stack that contains all elements that are excluded
65
-        // it is organized by parent elements, similar to $stack,
66
-        // but it is only populated when an element with exclusions is
67
-        // processed, i.e. there won't be empty exclusions.
68
-        $exclude_stack = array();
69
-
70
-        // variable that contains the start token while we are processing
71
-        // nodes. This enables error reporting to do its job
72
-        $start_token = false;
73
-        $context->register('CurrentToken', $start_token);
74
-
75
-        //####################################################################//
76
-        // Loop
77
-
78
-        // iterate through all start nodes. Determining the start node
79
-        // is complicated so it has been omitted from the loop construct
80
-        for ($i = 0, $size = count($tokens) ; $i < $size; ) {
81
-
82
-            //################################################################//
83
-            // Gather information on children
84
-
85
-            // child token accumulator
86
-            $child_tokens = array();
87
-
88
-            // scroll to the end of this node, report number, and collect
89
-            // all children
90
-            for ($j = $i, $depth = 0; ; $j++) {
91
-                if ($tokens[$j] instanceof HTMLPurifier_Token_Start) {
92
-                    $depth++;
93
-                    // skip token assignment on first iteration, this is the
94
-                    // token we currently are on
95
-                    if ($depth == 1) continue;
96
-                } elseif ($tokens[$j] instanceof HTMLPurifier_Token_End) {
97
-                    $depth--;
98
-                    // skip token assignment on last iteration, this is the
99
-                    // end token of the token we're currently on
100
-                    if ($depth == 0) break;
101
-                }
102
-                $child_tokens[] = $tokens[$j];
103
-            }
104
-
105
-            // $i is index of start token
106
-            // $j is index of end token
107
-
108
-            $start_token = $tokens[$i]; // to make token available via CurrentToken
109
-
110
-            //################################################################//
111
-            // Gather information on parent
112
-
113
-            // calculate parent information
114
-            if ($count = count($stack)) {
115
-                $parent_index = $stack[$count-1];
116
-                $parent_name  = $tokens[$parent_index]->name;
117
-                if ($parent_index == 0) {
118
-                    $parent_def   = $definition->info_parent_def;
119
-                } else {
120
-                    $parent_def   = $definition->info[$parent_name];
121
-                }
122
-            } else {
123
-                // processing as if the parent were the "root" node
124
-                // unknown info, it won't be used anyway, in the future,
125
-                // we may want to enforce one element only (this is
126
-                // necessary for HTML Purifier to clean entire documents
127
-                $parent_index = $parent_name = $parent_def = null;
128
-            }
129
-
130
-            // calculate context
131
-            if ($is_inline === false) {
132
-                // check if conditions make it inline
133
-                if (!empty($parent_def) && $parent_def->descendants_are_inline) {
134
-                    $is_inline = $count - 1;
135
-                }
136
-            } else {
137
-                // check if we're out of inline
138
-                if ($count === $is_inline) {
139
-                    $is_inline = false;
140
-                }
141
-            }
142
-
143
-            //################################################################//
144
-            // Determine whether element is explicitly excluded SGML-style
145
-
146
-            // determine whether or not element is excluded by checking all
147
-            // parent exclusions. The array should not be very large, two
148
-            // elements at most.
149
-            $excluded = false;
150
-            if (!empty($exclude_stack)) {
151
-                foreach ($exclude_stack as $lookup) {
152
-                    if (isset($lookup[$tokens[$i]->name])) {
153
-                        $excluded = true;
154
-                        // no need to continue processing
155
-                        break;
156
-                    }
157
-                }
158
-            }
159
-
160
-            //################################################################//
161
-            // Perform child validation
162
-
163
-            if ($excluded) {
164
-                // there is an exclusion, remove the entire node
165
-                $result = false;
166
-                $excludes = array(); // not used, but good to initialize anyway
167
-            } else {
168
-                // DEFINITION CALL
169
-                if ($i === 0) {
170
-                    // special processing for the first node
171
-                    $def = $definition->info_parent_def;
172
-                } else {
173
-                    $def = $definition->info[$tokens[$i]->name];
174
-
175
-                }
176
-
177
-                if (!empty($def->child)) {
178
-                    // have DTD child def validate children
179
-                    $result = $def->child->validateChildren(
180
-                        $child_tokens, $config, $context);
181
-                } else {
182
-                    // weird, no child definition, get rid of everything
183
-                    $result = false;
184
-                }
185
-
186
-                // determine whether or not this element has any exclusions
187
-                $excludes = $def->excludes;
188
-            }
189
-
190
-            // $result is now a bool or array
191
-
192
-            //################################################################//
193
-            // Process result by interpreting $result
194
-
195
-            if ($result === true || $child_tokens === $result) {
196
-                // leave the node as is
197
-
198
-                // register start token as a parental node start
199
-                $stack[] = $i;
200
-
201
-                // register exclusions if there are any
202
-                if (!empty($excludes)) $exclude_stack[] = $excludes;
203
-
204
-                // move cursor to next possible start node
205
-                $i++;
206
-
207
-            } elseif($result === false) {
208
-                // remove entire node
209
-
210
-                if ($e) {
211
-                    if ($excluded) {
212
-                        $e->send(E_ERROR, 'Strategy_FixNesting: Node excluded');
213
-                    } else {
214
-                        $e->send(E_ERROR, 'Strategy_FixNesting: Node removed');
215
-                    }
216
-                }
217
-
218
-                // calculate length of inner tokens and current tokens
219
-                $length = $j - $i + 1;
220
-
221
-                // perform removal
222
-                array_splice($tokens, $i, $length);
223
-
224
-                // update size
225
-                $size -= $length;
226
-
227
-                // there is no start token to register,
228
-                // current node is now the next possible start node
229
-                // unless it turns out that we need to do a double-check
230
-
231
-                // this is a rought heuristic that covers 100% of HTML's
232
-                // cases and 99% of all other cases. A child definition
233
-                // that would be tricked by this would be something like:
234
-                // ( | a b c) where it's all or nothing. Fortunately,
235
-                // our current implementation claims that that case would
236
-                // not allow empty, even if it did
237
-                if (!$parent_def->child->allow_empty) {
238
-                    // we need to do a double-check
239
-                    $i = $parent_index;
240
-                    array_pop($stack);
241
-                }
242
-
243
-                // PROJECTED OPTIMIZATION: Process all children elements before
244
-                // reprocessing parent node.
245
-
246
-            } else {
247
-                // replace node with $result
248
-
249
-                // calculate length of inner tokens
250
-                $length = $j - $i - 1;
251
-
252
-                if ($e) {
253
-                    if (empty($result) && $length) {
254
-                        $e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed');
255
-                    } else {
256
-                        $e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized');
257
-                    }
258
-                }
259
-
260
-                // perform replacement
261
-                array_splice($tokens, $i + 1, $length, $result);
262
-
263
-                // update size
264
-                $size -= $length;
265
-                $size += count($result);
266
-
267
-                // register start token as a parental node start
268
-                $stack[] = $i;
269
-
270
-                // register exclusions if there are any
271
-                if (!empty($excludes)) $exclude_stack[] = $excludes;
272
-
273
-                // move cursor to next possible start node
274
-                $i++;
275
-
276
-            }
277
-
278
-            //################################################################//
279
-            // Scroll to next start node
280
-
281
-            // We assume, at this point, that $i is the index of the token
282
-            // that is the first possible new start point for a node.
283
-
284
-            // Test if the token indeed is a start tag, if not, move forward
285
-            // and test again.
286
-            $size = count($tokens);
287
-            while ($i < $size and !$tokens[$i] instanceof HTMLPurifier_Token_Start) {
288
-                if ($tokens[$i] instanceof HTMLPurifier_Token_End) {
289
-                    // pop a token index off the stack if we ended a node
290
-                    array_pop($stack);
291
-                    // pop an exclusion lookup off exclusion stack if
292
-                    // we ended node and that node had exclusions
293
-                    if ($i == 0 || $i == $size - 1) {
294
-                        // use specialized var if it's the super-parent
295
-                        $s_excludes = $definition->info_parent_def->excludes;
296
-                    } else {
297
-                        $s_excludes = $definition->info[$tokens[$i]->name]->excludes;
298
-                    }
299
-                    if ($s_excludes) {
300
-                        array_pop($exclude_stack);
301
-                    }
302
-                }
303
-                $i++;
304
-            }
305
-
306
-        }
307
-
308
-        //####################################################################//
309
-        // Post-processing
310
-
311
-        // remove implicit parent tokens at the beginning and end
312
-        array_shift($tokens);
313
-        array_pop($tokens);
314
-
315
-        // remove context variables
316
-        $context->destroy('IsInline');
317
-        $context->destroy('CurrentToken');
318
-
319
-        //####################################################################//
320
-        // Return
321
-
322
-        return $tokens;
323
-
324
-    }
34
+	public function execute($tokens, $config, $context) {
35
+		//####################################################################//
36
+		// Pre-processing
37
+
38
+		// get a copy of the HTML definition
39
+		$definition = $config->getHTMLDefinition();
40
+
41
+		// insert implicit "parent" node, will be removed at end.
42
+		// DEFINITION CALL
43
+		$parent_name = $definition->info_parent;
44
+		array_unshift($tokens, new HTMLPurifier_Token_Start($parent_name));
45
+		$tokens[] = new HTMLPurifier_Token_End($parent_name);
46
+
47
+		// setup the context variable 'IsInline', for chameleon processing
48
+		// is 'false' when we are not inline, 'true' when it must always
49
+		// be inline, and an integer when it is inline for a certain
50
+		// branch of the document tree
51
+		$is_inline = $definition->info_parent_def->descendants_are_inline;
52
+		$context->register('IsInline', $is_inline);
53
+
54
+		// setup error collector
55
+		$e =& $context->get('ErrorCollector', true);
56
+
57
+		//####################################################################//
58
+		// Loop initialization
59
+
60
+		// stack that contains the indexes of all parents,
61
+		// $stack[count($stack)-1] being the current parent
62
+		$stack = array();
63
+
64
+		// stack that contains all elements that are excluded
65
+		// it is organized by parent elements, similar to $stack,
66
+		// but it is only populated when an element with exclusions is
67
+		// processed, i.e. there won't be empty exclusions.
68
+		$exclude_stack = array();
69
+
70
+		// variable that contains the start token while we are processing
71
+		// nodes. This enables error reporting to do its job
72
+		$start_token = false;
73
+		$context->register('CurrentToken', $start_token);
74
+
75
+		//####################################################################//
76
+		// Loop
77
+
78
+		// iterate through all start nodes. Determining the start node
79
+		// is complicated so it has been omitted from the loop construct
80
+		for ($i = 0, $size = count($tokens) ; $i < $size; ) {
81
+
82
+			//################################################################//
83
+			// Gather information on children
84
+
85
+			// child token accumulator
86
+			$child_tokens = array();
87
+
88
+			// scroll to the end of this node, report number, and collect
89
+			// all children
90
+			for ($j = $i, $depth = 0; ; $j++) {
91
+				if ($tokens[$j] instanceof HTMLPurifier_Token_Start) {
92
+					$depth++;
93
+					// skip token assignment on first iteration, this is the
94
+					// token we currently are on
95
+					if ($depth == 1) continue;
96
+				} elseif ($tokens[$j] instanceof HTMLPurifier_Token_End) {
97
+					$depth--;
98
+					// skip token assignment on last iteration, this is the
99
+					// end token of the token we're currently on
100
+					if ($depth == 0) break;
101
+				}
102
+				$child_tokens[] = $tokens[$j];
103
+			}
104
+
105
+			// $i is index of start token
106
+			// $j is index of end token
107
+
108
+			$start_token = $tokens[$i]; // to make token available via CurrentToken
109
+
110
+			//################################################################//
111
+			// Gather information on parent
112
+
113
+			// calculate parent information
114
+			if ($count = count($stack)) {
115
+				$parent_index = $stack[$count-1];
116
+				$parent_name  = $tokens[$parent_index]->name;
117
+				if ($parent_index == 0) {
118
+					$parent_def   = $definition->info_parent_def;
119
+				} else {
120
+					$parent_def   = $definition->info[$parent_name];
121
+				}
122
+			} else {
123
+				// processing as if the parent were the "root" node
124
+				// unknown info, it won't be used anyway, in the future,
125
+				// we may want to enforce one element only (this is
126
+				// necessary for HTML Purifier to clean entire documents
127
+				$parent_index = $parent_name = $parent_def = null;
128
+			}
129
+
130
+			// calculate context
131
+			if ($is_inline === false) {
132
+				// check if conditions make it inline
133
+				if (!empty($parent_def) && $parent_def->descendants_are_inline) {
134
+					$is_inline = $count - 1;
135
+				}
136
+			} else {
137
+				// check if we're out of inline
138
+				if ($count === $is_inline) {
139
+					$is_inline = false;
140
+				}
141
+			}
142
+
143
+			//################################################################//
144
+			// Determine whether element is explicitly excluded SGML-style
145
+
146
+			// determine whether or not element is excluded by checking all
147
+			// parent exclusions. The array should not be very large, two
148
+			// elements at most.
149
+			$excluded = false;
150
+			if (!empty($exclude_stack)) {
151
+				foreach ($exclude_stack as $lookup) {
152
+					if (isset($lookup[$tokens[$i]->name])) {
153
+						$excluded = true;
154
+						// no need to continue processing
155
+						break;
156
+					}
157
+				}
158
+			}
159
+
160
+			//################################################################//
161
+			// Perform child validation
162
+
163
+			if ($excluded) {
164
+				// there is an exclusion, remove the entire node
165
+				$result = false;
166
+				$excludes = array(); // not used, but good to initialize anyway
167
+			} else {
168
+				// DEFINITION CALL
169
+				if ($i === 0) {
170
+					// special processing for the first node
171
+					$def = $definition->info_parent_def;
172
+				} else {
173
+					$def = $definition->info[$tokens[$i]->name];
174
+
175
+				}
176
+
177
+				if (!empty($def->child)) {
178
+					// have DTD child def validate children
179
+					$result = $def->child->validateChildren(
180
+						$child_tokens, $config, $context);
181
+				} else {
182
+					// weird, no child definition, get rid of everything
183
+					$result = false;
184
+				}
185
+
186
+				// determine whether or not this element has any exclusions
187
+				$excludes = $def->excludes;
188
+			}
189
+
190
+			// $result is now a bool or array
191
+
192
+			//################################################################//
193
+			// Process result by interpreting $result
194
+
195
+			if ($result === true || $child_tokens === $result) {
196
+				// leave the node as is
197
+
198
+				// register start token as a parental node start
199
+				$stack[] = $i;
200
+
201
+				// register exclusions if there are any
202
+				if (!empty($excludes)) $exclude_stack[] = $excludes;
203
+
204
+				// move cursor to next possible start node
205
+				$i++;
206
+
207
+			} elseif($result === false) {
208
+				// remove entire node
209
+
210
+				if ($e) {
211
+					if ($excluded) {
212
+						$e->send(E_ERROR, 'Strategy_FixNesting: Node excluded');
213
+					} else {
214
+						$e->send(E_ERROR, 'Strategy_FixNesting: Node removed');
215
+					}
216
+				}
217
+
218
+				// calculate length of inner tokens and current tokens
219
+				$length = $j - $i + 1;
220
+
221
+				// perform removal
222
+				array_splice($tokens, $i, $length);
223
+
224
+				// update size
225
+				$size -= $length;
226
+
227
+				// there is no start token to register,
228
+				// current node is now the next possible start node
229
+				// unless it turns out that we need to do a double-check
230
+
231
+				// this is a rought heuristic that covers 100% of HTML's
232
+				// cases and 99% of all other cases. A child definition
233
+				// that would be tricked by this would be something like:
234
+				// ( | a b c) where it's all or nothing. Fortunately,
235
+				// our current implementation claims that that case would
236
+				// not allow empty, even if it did
237
+				if (!$parent_def->child->allow_empty) {
238
+					// we need to do a double-check
239
+					$i = $parent_index;
240
+					array_pop($stack);
241
+				}
242
+
243
+				// PROJECTED OPTIMIZATION: Process all children elements before
244
+				// reprocessing parent node.
245
+
246
+			} else {
247
+				// replace node with $result
248
+
249
+				// calculate length of inner tokens
250
+				$length = $j - $i - 1;
251
+
252
+				if ($e) {
253
+					if (empty($result) && $length) {
254
+						$e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed');
255
+					} else {
256
+						$e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized');
257
+					}
258
+				}
259
+
260
+				// perform replacement
261
+				array_splice($tokens, $i + 1, $length, $result);
262
+
263
+				// update size
264
+				$size -= $length;
265
+				$size += count($result);
266
+
267
+				// register start token as a parental node start
268
+				$stack[] = $i;
269
+
270
+				// register exclusions if there are any
271
+				if (!empty($excludes)) $exclude_stack[] = $excludes;
272
+
273
+				// move cursor to next possible start node
274
+				$i++;
275
+
276
+			}
277
+
278
+			//################################################################//
279
+			// Scroll to next start node
280
+
281
+			// We assume, at this point, that $i is the index of the token
282
+			// that is the first possible new start point for a node.
283
+
284
+			// Test if the token indeed is a start tag, if not, move forward
285
+			// and test again.
286
+			$size = count($tokens);
287
+			while ($i < $size and !$tokens[$i] instanceof HTMLPurifier_Token_Start) {
288
+				if ($tokens[$i] instanceof HTMLPurifier_Token_End) {
289
+					// pop a token index off the stack if we ended a node
290
+					array_pop($stack);
291
+					// pop an exclusion lookup off exclusion stack if
292
+					// we ended node and that node had exclusions
293
+					if ($i == 0 || $i == $size - 1) {
294
+						// use specialized var if it's the super-parent
295
+						$s_excludes = $definition->info_parent_def->excludes;
296
+					} else {
297
+						$s_excludes = $definition->info[$tokens[$i]->name]->excludes;
298
+					}
299
+					if ($s_excludes) {
300
+						array_pop($exclude_stack);
301
+					}
302
+				}
303
+				$i++;
304
+			}
305
+
306
+		}
307
+
308
+		//####################################################################//
309
+		// Post-processing
310
+
311
+		// remove implicit parent tokens at the beginning and end
312
+		array_shift($tokens);
313
+		array_pop($tokens);
314
+
315
+		// remove context variables
316
+		$context->destroy('IsInline');
317
+		$context->destroy('CurrentToken');
318
+
319
+		//####################################################################//
320
+		// Return
321
+
322
+		return $tokens;
323
+
324
+	}
325 325
 
326 326
 }
327 327
 
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -52,7 +52,7 @@  discard block
 block discarded – undo
52 52
         $context->register('IsInline', $is_inline);
53 53
 
54 54
         // setup error collector
55
-        $e =& $context->get('ErrorCollector', true);
55
+        $e = & $context->get('ErrorCollector', true);
56 56
 
57 57
         //####################################################################//
58 58
         // Loop initialization
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
 
78 78
         // iterate through all start nodes. Determining the start node
79 79
         // is complicated so it has been omitted from the loop construct
80
-        for ($i = 0, $size = count($tokens) ; $i < $size; ) {
80
+        for ($i = 0, $size = count($tokens); $i < $size;) {
81 81
 
82 82
             //################################################################//
83 83
             // Gather information on children
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
 
113 113
             // calculate parent information
114 114
             if ($count = count($stack)) {
115
-                $parent_index = $stack[$count-1];
115
+                $parent_index = $stack[$count - 1];
116 116
                 $parent_name  = $tokens[$parent_index]->name;
117 117
                 if ($parent_index == 0) {
118 118
                     $parent_def   = $definition->info_parent_def;
@@ -204,7 +204,7 @@  discard block
 block discarded – undo
204 204
                 // move cursor to next possible start node
205 205
                 $i++;
206 206
 
207
-            } elseif($result === false) {
207
+            } elseif ($result === false) {
208 208
                 // remove entire node
209 209
 
210 210
                 if ($e) {
Please login to merge, or discard this patch.
Braces   +12 added lines, -4 removed lines patch added patch discarded remove patch
@@ -92,12 +92,16 @@  discard block
 block discarded – undo
92 92
                     $depth++;
93 93
                     // skip token assignment on first iteration, this is the
94 94
                     // token we currently are on
95
-                    if ($depth == 1) continue;
95
+                    if ($depth == 1) {
96
+                    	continue;
97
+                    }
96 98
                 } elseif ($tokens[$j] instanceof HTMLPurifier_Token_End) {
97 99
                     $depth--;
98 100
                     // skip token assignment on last iteration, this is the
99 101
                     // end token of the token we're currently on
100
-                    if ($depth == 0) break;
102
+                    if ($depth == 0) {
103
+                    	break;
104
+                    }
101 105
                 }
102 106
                 $child_tokens[] = $tokens[$j];
103 107
             }
@@ -199,7 +203,9 @@  discard block
 block discarded – undo
199 203
                 $stack[] = $i;
200 204
 
201 205
                 // register exclusions if there are any
202
-                if (!empty($excludes)) $exclude_stack[] = $excludes;
206
+                if (!empty($excludes)) {
207
+                	$exclude_stack[] = $excludes;
208
+                }
203 209
 
204 210
                 // move cursor to next possible start node
205 211
                 $i++;
@@ -268,7 +274,9 @@  discard block
 block discarded – undo
268 274
                 $stack[] = $i;
269 275
 
270 276
                 // register exclusions if there are any
271
-                if (!empty($excludes)) $exclude_stack[] = $excludes;
277
+                if (!empty($excludes)) {
278
+                	$exclude_stack[] = $excludes;
279
+                }
272 280
 
273 281
                 // move cursor to next possible start node
274 282
                 $i++;
Please login to merge, or discard this patch.
security/htmlpurifier/library/HTMLPurifier/Strategy/MakeWellFormed.php 3 patches
Indentation   +512 added lines, -512 removed lines patch added patch discarded remove patch
@@ -14,518 +14,518 @@
 block discarded – undo
14 14
 class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
15 15
 {
16 16
 
17
-    /**
18
-     * Array stream of tokens being processed.
19
-     */
20
-    protected $tokens;
21
-
22
-    /**
23
-     * Current index in $tokens.
24
-     */
25
-    protected $t;
26
-
27
-    /**
28
-     * Current nesting of elements.
29
-     */
30
-    protected $stack;
31
-
32
-    /**
33
-     * Injectors active in this stream processing.
34
-     */
35
-    protected $injectors;
36
-
37
-    /**
38
-     * Current instance of HTMLPurifier_Config.
39
-     */
40
-    protected $config;
41
-
42
-    /**
43
-     * Current instance of HTMLPurifier_Context.
44
-     */
45
-    protected $context;
46
-
47
-    public function execute($tokens, $config, $context) {
48
-
49
-        $definition = $config->getHTMLDefinition();
50
-
51
-        // local variables
52
-        $generator = new HTMLPurifier_Generator($config, $context);
53
-        $escape_invalid_tags = $config->get('Core.EscapeInvalidTags');
54
-        // used for autoclose early abortion
55
-        $global_parent_allowed_elements = array();
56
-        if (isset($definition->info[$definition->info_parent])) {
57
-            // may be unset under testing circumstances
58
-            $global_parent_allowed_elements = $definition->info[$definition->info_parent]->child->getAllowedElements($config);
59
-        }
60
-        $e = $context->get('ErrorCollector', true);
61
-        $t = false; // token index
62
-        $i = false; // injector index
63
-        $token      = false; // the current token
64
-        $reprocess  = false; // whether or not to reprocess the same token
65
-        $stack = array();
66
-
67
-        // member variables
68
-        $this->stack   =& $stack;
69
-        $this->t       =& $t;
70
-        $this->tokens  =& $tokens;
71
-        $this->config  = $config;
72
-        $this->context = $context;
73
-
74
-        // context variables
75
-        $context->register('CurrentNesting', $stack);
76
-        $context->register('InputIndex',     $t);
77
-        $context->register('InputTokens',    $tokens);
78
-        $context->register('CurrentToken',   $token);
79
-
80
-        // -- begin INJECTOR --
81
-
82
-        $this->injectors = array();
83
-
84
-        $injectors = $config->getBatch('AutoFormat');
85
-        $def_injectors = $definition->info_injector;
86
-        $custom_injectors = $injectors['Custom'];
87
-        unset($injectors['Custom']); // special case
88
-        foreach ($injectors as $injector => $b) {
89
-            // XXX: Fix with a legitimate lookup table of enabled filters
90
-            if (strpos($injector, '.') !== false) continue;
91
-            $injector = "HTMLPurifier_Injector_$injector";
92
-            if (!$b) continue;
93
-            $this->injectors[] = new $injector;
94
-        }
95
-        foreach ($def_injectors as $injector) {
96
-            // assumed to be objects
97
-            $this->injectors[] = $injector;
98
-        }
99
-        foreach ($custom_injectors as $injector) {
100
-            if (!$injector) continue;
101
-            if (is_string($injector)) {
102
-                $injector = "HTMLPurifier_Injector_$injector";
103
-                $injector = new $injector;
104
-            }
105
-            $this->injectors[] = $injector;
106
-        }
107
-
108
-        // give the injectors references to the definition and context
109
-        // variables for performance reasons
110
-        foreach ($this->injectors as $ix => $injector) {
111
-            $error = $injector->prepare($config, $context);
112
-            if (!$error) continue;
113
-            array_splice($this->injectors, $ix, 1); // rm the injector
114
-            trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING);
115
-        }
116
-
117
-        // -- end INJECTOR --
118
-
119
-        // a note on reprocessing:
120
-        //      In order to reduce code duplication, whenever some code needs
121
-        //      to make HTML changes in order to make things "correct", the
122
-        //      new HTML gets sent through the purifier, regardless of its
123
-        //      status. This means that if we add a start token, because it
124
-        //      was totally necessary, we don't have to update nesting; we just
125
-        //      punt ($reprocess = true; continue;) and it does that for us.
126
-
127
-        // isset is in loop because $tokens size changes during loop exec
128
-        for (
129
-            $t = 0;
130
-            $t == 0 || isset($tokens[$t - 1]);
131
-            // only increment if we don't need to reprocess
132
-            $reprocess ? $reprocess = false : $t++
133
-        ) {
134
-
135
-            // check for a rewind
136
-            if (is_int($i) && $i >= 0) {
137
-                // possibility: disable rewinding if the current token has a
138
-                // rewind set on it already. This would offer protection from
139
-                // infinite loop, but might hinder some advanced rewinding.
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) {
144
-                        $t--;
145
-                        $prev = $tokens[$t];
146
-                        // indicate that other injectors should not process this token,
147
-                        // but we need to reprocess it
148
-                        unset($prev->skip[$i]);
149
-                        $prev->rewind = $i;
150
-                        if ($prev instanceof HTMLPurifier_Token_Start) array_pop($this->stack);
151
-                        elseif ($prev instanceof HTMLPurifier_Token_End) $this->stack[] = $prev->start;
152
-                    }
153
-                }
154
-                $i = false;
155
-            }
156
-
157
-            // handle case of document end
158
-            if (!isset($tokens[$t])) {
159
-                // kill processing if stack is empty
160
-                if (empty($this->stack)) break;
161
-
162
-                // peek
163
-                $top_nesting = array_pop($this->stack);
164
-                $this->stack[] = $top_nesting;
165
-
166
-                // send error [TagClosedSuppress]
167
-                if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) {
168
-                    $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting);
169
-                }
170
-
171
-                // append, don't splice, since this is the end
172
-                $tokens[] = new HTMLPurifier_Token_End($top_nesting->name);
173
-
174
-                // punt!
175
-                $reprocess = true;
176
-                continue;
177
-            }
178
-
179
-            $token = $tokens[$t];
180
-
181
-            //echo '<br>'; printTokens($tokens, $t); printTokens($this->stack);
182
-            //flush();
183
-
184
-            // quick-check: if it's not a tag, no need to process
185
-            if (empty($token->is_tag)) {
186
-                if ($token instanceof HTMLPurifier_Token_Text) {
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);
191
-                        $this->processToken($token, $i);
192
-                        $reprocess = true;
193
-                        break;
194
-                    }
195
-                }
196
-                // another possibility is a comment
197
-                continue;
198
-            }
199
-
200
-            if (isset($definition->info[$token->name])) {
201
-                $type = $definition->info[$token->name]->child->type;
202
-            } else {
203
-                $type = false; // Type is unknown, treat accordingly
204
-            }
205
-
206
-            // quick tag checks: anything that's *not* an end tag
207
-            $ok = false;
208
-            if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) {
209
-                // claims to be a start tag but is empty
210
-                $token = new HTMLPurifier_Token_Empty($token->name, $token->attr, $token->line, $token->col, $token->armor);
211
-                $ok = true;
212
-            } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) {
213
-                // claims to be empty but really is a start tag
214
-                $this->swap(new HTMLPurifier_Token_End($token->name));
215
-                $this->insertBefore(new HTMLPurifier_Token_Start($token->name, $token->attr, $token->line, $token->col, $token->armor));
216
-                // punt (since we had to modify the input stream in a non-trivial way)
217
-                $reprocess = true;
218
-                continue;
219
-            } elseif ($token instanceof HTMLPurifier_Token_Empty) {
220
-                // real empty token
221
-                $ok = true;
222
-            } elseif ($token instanceof HTMLPurifier_Token_Start) {
223
-                // start tag
224
-
225
-                // ...unless they also have to close their parent
226
-                if (!empty($this->stack)) {
227
-
228
-                    // Performance note: you might think that it's rather
229
-                    // inefficient, recalculating the autoclose information
230
-                    // for every tag that a token closes (since when we
231
-                    // do an autoclose, we push a new token into the
232
-                    // stream and then /process/ that, before
233
-                    // re-processing this token.)  But this is
234
-                    // necessary, because an injector can make an
235
-                    // arbitrary transformations to the autoclosing
236
-                    // tokens we introduce, so things may have changed
237
-                    // in the meantime.  Also, doing the inefficient thing is
238
-                    // "easy" to reason about (for certain perverse definitions
239
-                    // of "easy")
240
-
241
-                    $parent = array_pop($this->stack);
242
-                    $this->stack[] = $parent;
243
-
244
-                    if (isset($definition->info[$parent->name])) {
245
-                        $elements = $definition->info[$parent->name]->child->getAllowedElements($config);
246
-                        $autoclose = !isset($elements[$token->name]);
247
-                    } else {
248
-                        $autoclose = false;
249
-                    }
250
-
251
-                    if ($autoclose && $definition->info[$token->name]->wrap) {
252
-                        // Check if an element can be wrapped by another 
253
-                        // element to make it valid in a context (for 
254
-                        // example, <ul><ul> needs a <li> in between)
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);
261
-                            $this->insertBefore($newtoken);
262
-                            $reprocess = true;
263
-                            continue;
264
-                        }
265
-                    }
266
-
267
-                    $carryover = false;
268
-                    if ($autoclose && $definition->info[$parent->name]->formatting) {
269
-                        $carryover = true;
270
-                    }
271
-
272
-                    if ($autoclose) {
273
-                        // check if this autoclose is doomed to fail
274
-                        // (this rechecks $parent, which his harmless)
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;
281
-                                    break;
282
-                                }
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;
289
-                                        break;
290
-                                    }
291
-                                }
292
-                            }
293
-                        }
294
-                        if ($autoclose_ok) {
295
-                            // errors need to be updated
296
-                            $new_token = new HTMLPurifier_Token_End($parent->name);
297
-                            $new_token->start = $parent;
298
-                            if ($carryover) {
299
-                                $element = clone $parent;
300
-                                // [TagClosedAuto]
301
-                                $element->armor['MakeWellFormed_TagClosedError'] = true;
302
-                                $element->carryover = true;
303
-                                $this->processToken(array($new_token, $token, $element));
304
-                            } else {
305
-                                $this->insertBefore($new_token);
306
-                            }
307
-                            // [TagClosedSuppress]
308
-                            if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) {
309
-                                if (!$carryover) {
310
-                                    $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent);
311
-                                } else {
312
-                                    $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent);
313
-                                }
314
-                            }
315
-                        } else {
316
-                            $this->remove();
317
-                        }
318
-                        $reprocess = true;
319
-                        continue;
320
-                    }
321
-
322
-                }
323
-                $ok = true;
324
-            }
325
-
326
-            if ($ok) {
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);
331
-                    $this->processToken($token, $i);
332
-                    $reprocess = true;
333
-                    break;
334
-                }
335
-                if (!$reprocess) {
336
-                    // ah, nothing interesting happened; do normal processing
337
-                    $this->swap($token);
338
-                    if ($token instanceof HTMLPurifier_Token_Start) {
339
-                        $this->stack[] = $token;
340
-                    } elseif ($token instanceof HTMLPurifier_Token_End) {
341
-                        throw new HTMLPurifier_Exception('Improper handling of end tag in start code; possible error in MakeWellFormed');
342
-                    }
343
-                }
344
-                continue;
345
-            }
346
-
347
-            // sanity check: we should be dealing with a closing tag
348
-            if (!$token instanceof HTMLPurifier_Token_End) {
349
-                throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier');
350
-            }
351
-
352
-            // make sure that we have something open
353
-            if (empty($this->stack)) {
354
-                if ($escape_invalid_tags) {
355
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text');
356
-                    $this->swap(new HTMLPurifier_Token_Text(
357
-                        $generator->generateFromToken($token)
358
-                    ));
359
-                } else {
360
-                    $this->remove();
361
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed');
362
-                }
363
-                $reprocess = true;
364
-                continue;
365
-            }
366
-
367
-            // first, check for the simplest case: everything closes neatly.
368
-            // Eventually, everything passes through here; if there are problems
369
-            // we modify the input stream accordingly and then punt, so that
370
-            // the tokens get processed again.
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);
378
-                    $this->processToken($token, $i);
379
-                    $this->stack[] = $current_parent;
380
-                    $reprocess = true;
381
-                    break;
382
-                }
383
-                continue;
384
-            }
385
-
386
-            // okay, so we're trying to close the wrong tag
387
-
388
-            // undo the pop previous pop
389
-            $this->stack[] = $current_parent;
390
-
391
-            // scroll back the entire nest, trying to find our tag.
392
-            // (feature could be to specify how far you'd like to go)
393
-            $size = count($this->stack);
394
-            // -2 because -1 is the last element, but we already checked that
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);
399
-                    break;
400
-                }
401
-            }
402
-
403
-            // we didn't find the tag, so remove
404
-            if ($skipped_tags === false) {
405
-                if ($escape_invalid_tags) {
406
-                    $this->swap(new HTMLPurifier_Token_Text(
407
-                        $generator->generateFromToken($token)
408
-                    ));
409
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text');
410
-                } else {
411
-                    $this->remove();
412
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed');
413
-                }
414
-                $reprocess = true;
415
-                continue;
416
-            }
417
-
418
-            // do errors, in REVERSE $j order: a,b,c with </a></b></c>
419
-            $c = count($skipped_tags);
420
-            if ($e) {
421
-                for ($j = $c - 1; $j > 0; $j--) {
422
-                    // notice we exclude $j == 0, i.e. the current ending tag, from
423
-                    // the errors... [TagClosedSuppress]
424
-                    if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) {
425
-                        $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]);
426
-                    }
427
-                }
428
-            }
429
-
430
-            // insert tags, in FORWARD $j order: c,b,a with </a></b></c>
431
-            $replace = array($token);
432
-            for ($j = 1; $j < $c; $j++) {
433
-                // ...as well as from the insertions
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) {
438
-                    // [TagClosedAuto]
439
-                    $element = clone $skipped_tags[$j];
440
-                    $element->carryover = true;
441
-                    $element->armor['MakeWellFormed_TagClosedError'] = true;
442
-                    $replace[] = $element;
443
-                }
444
-            }
445
-            $this->processToken($replace);
446
-            $reprocess = true;
447
-            continue;
448
-        }
449
-
450
-        $context->destroy('CurrentNesting');
451
-        $context->destroy('InputTokens');
452
-        $context->destroy('InputIndex');
453
-        $context->destroy('CurrentToken');
454
-
455
-        unset($this->injectors, $this->stack, $this->tokens, $this->t);
456
-        return $tokens;
457
-    }
458
-
459
-    /**
460
-     * Processes arbitrary token values for complicated substitution patterns.
461
-     * In general:
462
-     *
463
-     * If $token is an array, it is a list of tokens to substitute for the
464
-     * current token. These tokens then get individually processed. If there
465
-     * is a leading integer in the list, that integer determines how many
466
-     * tokens from the stream should be removed.
467
-     *
468
-     * If $token is a regular token, it is swapped with the current token.
469
-     *
470
-     * If $token is false, the current token is deleted.
471
-     *
472
-     * If $token is an integer, that number of tokens (with the first token
473
-     * being the current one) will be deleted.
474
-     *
475
-     * @param $token Token substitution value
476
-     * @param $injector Injector that performed the substitution; default is if
477
-     *        this is not an injector related operation.
478
-     */
479
-    protected function processToken($token, $injector = -1) {
480
-
481
-        // normalize forms of token
482
-        if (is_object($token)) $token = array(1, $token);
483
-        if (is_int($token))    $token = array($token);
484
-        if ($token === false)  $token = array(1);
485
-        if (!is_array($token)) throw new HTMLPurifier_Exception('Invalid token type from injector');
486
-        if (!is_int($token[0])) array_unshift($token, 1);
487
-        if ($token[0] === 0) throw new HTMLPurifier_Exception('Deleting zero tokens is not valid');
488
-
489
-        // $token is now an array with the following form:
490
-        // array(number nodes to delete, new node 1, new node 2, ...)
491
-
492
-        $delete = array_shift($token);
493
-        $old = array_splice($this->tokens, $this->t, $delete, $token);
494
-
495
-        if ($injector > -1) {
496
-            // determine appropriate skips
497
-            $oldskip = isset($old[0]) ? $old[0]->skip : array();
498
-            foreach ($token as $object) {
499
-                $object->skip = $oldskip;
500
-                $object->skip[$injector] = true;
501
-            }
502
-        }
503
-
504
-    }
505
-
506
-    /**
507
-     * Inserts a token before the current token. Cursor now points to
508
-     * this token.  You must reprocess after this.
509
-     */
510
-    private function insertBefore($token) {
511
-        array_splice($this->tokens, $this->t, 0, array($token));
512
-    }
513
-
514
-    /**
515
-     * Removes current token. Cursor now points to new token occupying previously
516
-     * occupied space.  You must reprocess after this.
517
-     */
518
-    private function remove() {
519
-        array_splice($this->tokens, $this->t, 1);
520
-    }
521
-
522
-    /**
523
-     * Swap current token with new token. Cursor points to new token (no
524
-     * change).  You must reprocess after this.
525
-     */
526
-    private function swap($token) {
527
-        $this->tokens[$this->t] = $token;
528
-    }
17
+	/**
18
+	 * Array stream of tokens being processed.
19
+	 */
20
+	protected $tokens;
21
+
22
+	/**
23
+	 * Current index in $tokens.
24
+	 */
25
+	protected $t;
26
+
27
+	/**
28
+	 * Current nesting of elements.
29
+	 */
30
+	protected $stack;
31
+
32
+	/**
33
+	 * Injectors active in this stream processing.
34
+	 */
35
+	protected $injectors;
36
+
37
+	/**
38
+	 * Current instance of HTMLPurifier_Config.
39
+	 */
40
+	protected $config;
41
+
42
+	/**
43
+	 * Current instance of HTMLPurifier_Context.
44
+	 */
45
+	protected $context;
46
+
47
+	public function execute($tokens, $config, $context) {
48
+
49
+		$definition = $config->getHTMLDefinition();
50
+
51
+		// local variables
52
+		$generator = new HTMLPurifier_Generator($config, $context);
53
+		$escape_invalid_tags = $config->get('Core.EscapeInvalidTags');
54
+		// used for autoclose early abortion
55
+		$global_parent_allowed_elements = array();
56
+		if (isset($definition->info[$definition->info_parent])) {
57
+			// may be unset under testing circumstances
58
+			$global_parent_allowed_elements = $definition->info[$definition->info_parent]->child->getAllowedElements($config);
59
+		}
60
+		$e = $context->get('ErrorCollector', true);
61
+		$t = false; // token index
62
+		$i = false; // injector index
63
+		$token      = false; // the current token
64
+		$reprocess  = false; // whether or not to reprocess the same token
65
+		$stack = array();
66
+
67
+		// member variables
68
+		$this->stack   =& $stack;
69
+		$this->t       =& $t;
70
+		$this->tokens  =& $tokens;
71
+		$this->config  = $config;
72
+		$this->context = $context;
73
+
74
+		// context variables
75
+		$context->register('CurrentNesting', $stack);
76
+		$context->register('InputIndex',     $t);
77
+		$context->register('InputTokens',    $tokens);
78
+		$context->register('CurrentToken',   $token);
79
+
80
+		// -- begin INJECTOR --
81
+
82
+		$this->injectors = array();
83
+
84
+		$injectors = $config->getBatch('AutoFormat');
85
+		$def_injectors = $definition->info_injector;
86
+		$custom_injectors = $injectors['Custom'];
87
+		unset($injectors['Custom']); // special case
88
+		foreach ($injectors as $injector => $b) {
89
+			// XXX: Fix with a legitimate lookup table of enabled filters
90
+			if (strpos($injector, '.') !== false) continue;
91
+			$injector = "HTMLPurifier_Injector_$injector";
92
+			if (!$b) continue;
93
+			$this->injectors[] = new $injector;
94
+		}
95
+		foreach ($def_injectors as $injector) {
96
+			// assumed to be objects
97
+			$this->injectors[] = $injector;
98
+		}
99
+		foreach ($custom_injectors as $injector) {
100
+			if (!$injector) continue;
101
+			if (is_string($injector)) {
102
+				$injector = "HTMLPurifier_Injector_$injector";
103
+				$injector = new $injector;
104
+			}
105
+			$this->injectors[] = $injector;
106
+		}
107
+
108
+		// give the injectors references to the definition and context
109
+		// variables for performance reasons
110
+		foreach ($this->injectors as $ix => $injector) {
111
+			$error = $injector->prepare($config, $context);
112
+			if (!$error) continue;
113
+			array_splice($this->injectors, $ix, 1); // rm the injector
114
+			trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING);
115
+		}
116
+
117
+		// -- end INJECTOR --
118
+
119
+		// a note on reprocessing:
120
+		//      In order to reduce code duplication, whenever some code needs
121
+		//      to make HTML changes in order to make things "correct", the
122
+		//      new HTML gets sent through the purifier, regardless of its
123
+		//      status. This means that if we add a start token, because it
124
+		//      was totally necessary, we don't have to update nesting; we just
125
+		//      punt ($reprocess = true; continue;) and it does that for us.
126
+
127
+		// isset is in loop because $tokens size changes during loop exec
128
+		for (
129
+			$t = 0;
130
+			$t == 0 || isset($tokens[$t - 1]);
131
+			// only increment if we don't need to reprocess
132
+			$reprocess ? $reprocess = false : $t++
133
+		) {
134
+
135
+			// check for a rewind
136
+			if (is_int($i) && $i >= 0) {
137
+				// possibility: disable rewinding if the current token has a
138
+				// rewind set on it already. This would offer protection from
139
+				// infinite loop, but might hinder some advanced rewinding.
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) {
144
+						$t--;
145
+						$prev = $tokens[$t];
146
+						// indicate that other injectors should not process this token,
147
+						// but we need to reprocess it
148
+						unset($prev->skip[$i]);
149
+						$prev->rewind = $i;
150
+						if ($prev instanceof HTMLPurifier_Token_Start) array_pop($this->stack);
151
+						elseif ($prev instanceof HTMLPurifier_Token_End) $this->stack[] = $prev->start;
152
+					}
153
+				}
154
+				$i = false;
155
+			}
156
+
157
+			// handle case of document end
158
+			if (!isset($tokens[$t])) {
159
+				// kill processing if stack is empty
160
+				if (empty($this->stack)) break;
161
+
162
+				// peek
163
+				$top_nesting = array_pop($this->stack);
164
+				$this->stack[] = $top_nesting;
165
+
166
+				// send error [TagClosedSuppress]
167
+				if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) {
168
+					$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting);
169
+				}
170
+
171
+				// append, don't splice, since this is the end
172
+				$tokens[] = new HTMLPurifier_Token_End($top_nesting->name);
173
+
174
+				// punt!
175
+				$reprocess = true;
176
+				continue;
177
+			}
178
+
179
+			$token = $tokens[$t];
180
+
181
+			//echo '<br>'; printTokens($tokens, $t); printTokens($this->stack);
182
+			//flush();
183
+
184
+			// quick-check: if it's not a tag, no need to process
185
+			if (empty($token->is_tag)) {
186
+				if ($token instanceof HTMLPurifier_Token_Text) {
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);
191
+						$this->processToken($token, $i);
192
+						$reprocess = true;
193
+						break;
194
+					}
195
+				}
196
+				// another possibility is a comment
197
+				continue;
198
+			}
199
+
200
+			if (isset($definition->info[$token->name])) {
201
+				$type = $definition->info[$token->name]->child->type;
202
+			} else {
203
+				$type = false; // Type is unknown, treat accordingly
204
+			}
205
+
206
+			// quick tag checks: anything that's *not* an end tag
207
+			$ok = false;
208
+			if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) {
209
+				// claims to be a start tag but is empty
210
+				$token = new HTMLPurifier_Token_Empty($token->name, $token->attr, $token->line, $token->col, $token->armor);
211
+				$ok = true;
212
+			} elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) {
213
+				// claims to be empty but really is a start tag
214
+				$this->swap(new HTMLPurifier_Token_End($token->name));
215
+				$this->insertBefore(new HTMLPurifier_Token_Start($token->name, $token->attr, $token->line, $token->col, $token->armor));
216
+				// punt (since we had to modify the input stream in a non-trivial way)
217
+				$reprocess = true;
218
+				continue;
219
+			} elseif ($token instanceof HTMLPurifier_Token_Empty) {
220
+				// real empty token
221
+				$ok = true;
222
+			} elseif ($token instanceof HTMLPurifier_Token_Start) {
223
+				// start tag
224
+
225
+				// ...unless they also have to close their parent
226
+				if (!empty($this->stack)) {
227
+
228
+					// Performance note: you might think that it's rather
229
+					// inefficient, recalculating the autoclose information
230
+					// for every tag that a token closes (since when we
231
+					// do an autoclose, we push a new token into the
232
+					// stream and then /process/ that, before
233
+					// re-processing this token.)  But this is
234
+					// necessary, because an injector can make an
235
+					// arbitrary transformations to the autoclosing
236
+					// tokens we introduce, so things may have changed
237
+					// in the meantime.  Also, doing the inefficient thing is
238
+					// "easy" to reason about (for certain perverse definitions
239
+					// of "easy")
240
+
241
+					$parent = array_pop($this->stack);
242
+					$this->stack[] = $parent;
243
+
244
+					if (isset($definition->info[$parent->name])) {
245
+						$elements = $definition->info[$parent->name]->child->getAllowedElements($config);
246
+						$autoclose = !isset($elements[$token->name]);
247
+					} else {
248
+						$autoclose = false;
249
+					}
250
+
251
+					if ($autoclose && $definition->info[$token->name]->wrap) {
252
+						// Check if an element can be wrapped by another 
253
+						// element to make it valid in a context (for 
254
+						// example, <ul><ul> needs a <li> in between)
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);
261
+							$this->insertBefore($newtoken);
262
+							$reprocess = true;
263
+							continue;
264
+						}
265
+					}
266
+
267
+					$carryover = false;
268
+					if ($autoclose && $definition->info[$parent->name]->formatting) {
269
+						$carryover = true;
270
+					}
271
+
272
+					if ($autoclose) {
273
+						// check if this autoclose is doomed to fail
274
+						// (this rechecks $parent, which his harmless)
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;
281
+									break;
282
+								}
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;
289
+										break;
290
+									}
291
+								}
292
+							}
293
+						}
294
+						if ($autoclose_ok) {
295
+							// errors need to be updated
296
+							$new_token = new HTMLPurifier_Token_End($parent->name);
297
+							$new_token->start = $parent;
298
+							if ($carryover) {
299
+								$element = clone $parent;
300
+								// [TagClosedAuto]
301
+								$element->armor['MakeWellFormed_TagClosedError'] = true;
302
+								$element->carryover = true;
303
+								$this->processToken(array($new_token, $token, $element));
304
+							} else {
305
+								$this->insertBefore($new_token);
306
+							}
307
+							// [TagClosedSuppress]
308
+							if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) {
309
+								if (!$carryover) {
310
+									$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent);
311
+								} else {
312
+									$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent);
313
+								}
314
+							}
315
+						} else {
316
+							$this->remove();
317
+						}
318
+						$reprocess = true;
319
+						continue;
320
+					}
321
+
322
+				}
323
+				$ok = true;
324
+			}
325
+
326
+			if ($ok) {
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);
331
+					$this->processToken($token, $i);
332
+					$reprocess = true;
333
+					break;
334
+				}
335
+				if (!$reprocess) {
336
+					// ah, nothing interesting happened; do normal processing
337
+					$this->swap($token);
338
+					if ($token instanceof HTMLPurifier_Token_Start) {
339
+						$this->stack[] = $token;
340
+					} elseif ($token instanceof HTMLPurifier_Token_End) {
341
+						throw new HTMLPurifier_Exception('Improper handling of end tag in start code; possible error in MakeWellFormed');
342
+					}
343
+				}
344
+				continue;
345
+			}
346
+
347
+			// sanity check: we should be dealing with a closing tag
348
+			if (!$token instanceof HTMLPurifier_Token_End) {
349
+				throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier');
350
+			}
351
+
352
+			// make sure that we have something open
353
+			if (empty($this->stack)) {
354
+				if ($escape_invalid_tags) {
355
+					if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text');
356
+					$this->swap(new HTMLPurifier_Token_Text(
357
+						$generator->generateFromToken($token)
358
+					));
359
+				} else {
360
+					$this->remove();
361
+					if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed');
362
+				}
363
+				$reprocess = true;
364
+				continue;
365
+			}
366
+
367
+			// first, check for the simplest case: everything closes neatly.
368
+			// Eventually, everything passes through here; if there are problems
369
+			// we modify the input stream accordingly and then punt, so that
370
+			// the tokens get processed again.
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);
378
+					$this->processToken($token, $i);
379
+					$this->stack[] = $current_parent;
380
+					$reprocess = true;
381
+					break;
382
+				}
383
+				continue;
384
+			}
385
+
386
+			// okay, so we're trying to close the wrong tag
387
+
388
+			// undo the pop previous pop
389
+			$this->stack[] = $current_parent;
390
+
391
+			// scroll back the entire nest, trying to find our tag.
392
+			// (feature could be to specify how far you'd like to go)
393
+			$size = count($this->stack);
394
+			// -2 because -1 is the last element, but we already checked that
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);
399
+					break;
400
+				}
401
+			}
402
+
403
+			// we didn't find the tag, so remove
404
+			if ($skipped_tags === false) {
405
+				if ($escape_invalid_tags) {
406
+					$this->swap(new HTMLPurifier_Token_Text(
407
+						$generator->generateFromToken($token)
408
+					));
409
+					if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text');
410
+				} else {
411
+					$this->remove();
412
+					if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed');
413
+				}
414
+				$reprocess = true;
415
+				continue;
416
+			}
417
+
418
+			// do errors, in REVERSE $j order: a,b,c with </a></b></c>
419
+			$c = count($skipped_tags);
420
+			if ($e) {
421
+				for ($j = $c - 1; $j > 0; $j--) {
422
+					// notice we exclude $j == 0, i.e. the current ending tag, from
423
+					// the errors... [TagClosedSuppress]
424
+					if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) {
425
+						$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]);
426
+					}
427
+				}
428
+			}
429
+
430
+			// insert tags, in FORWARD $j order: c,b,a with </a></b></c>
431
+			$replace = array($token);
432
+			for ($j = 1; $j < $c; $j++) {
433
+				// ...as well as from the insertions
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) {
438
+					// [TagClosedAuto]
439
+					$element = clone $skipped_tags[$j];
440
+					$element->carryover = true;
441
+					$element->armor['MakeWellFormed_TagClosedError'] = true;
442
+					$replace[] = $element;
443
+				}
444
+			}
445
+			$this->processToken($replace);
446
+			$reprocess = true;
447
+			continue;
448
+		}
449
+
450
+		$context->destroy('CurrentNesting');
451
+		$context->destroy('InputTokens');
452
+		$context->destroy('InputIndex');
453
+		$context->destroy('CurrentToken');
454
+
455
+		unset($this->injectors, $this->stack, $this->tokens, $this->t);
456
+		return $tokens;
457
+	}
458
+
459
+	/**
460
+	 * Processes arbitrary token values for complicated substitution patterns.
461
+	 * In general:
462
+	 *
463
+	 * If $token is an array, it is a list of tokens to substitute for the
464
+	 * current token. These tokens then get individually processed. If there
465
+	 * is a leading integer in the list, that integer determines how many
466
+	 * tokens from the stream should be removed.
467
+	 *
468
+	 * If $token is a regular token, it is swapped with the current token.
469
+	 *
470
+	 * If $token is false, the current token is deleted.
471
+	 *
472
+	 * If $token is an integer, that number of tokens (with the first token
473
+	 * being the current one) will be deleted.
474
+	 *
475
+	 * @param $token Token substitution value
476
+	 * @param $injector Injector that performed the substitution; default is if
477
+	 *        this is not an injector related operation.
478
+	 */
479
+	protected function processToken($token, $injector = -1) {
480
+
481
+		// normalize forms of token
482
+		if (is_object($token)) $token = array(1, $token);
483
+		if (is_int($token))    $token = array($token);
484
+		if ($token === false)  $token = array(1);
485
+		if (!is_array($token)) throw new HTMLPurifier_Exception('Invalid token type from injector');
486
+		if (!is_int($token[0])) array_unshift($token, 1);
487
+		if ($token[0] === 0) throw new HTMLPurifier_Exception('Deleting zero tokens is not valid');
488
+
489
+		// $token is now an array with the following form:
490
+		// array(number nodes to delete, new node 1, new node 2, ...)
491
+
492
+		$delete = array_shift($token);
493
+		$old = array_splice($this->tokens, $this->t, $delete, $token);
494
+
495
+		if ($injector > -1) {
496
+			// determine appropriate skips
497
+			$oldskip = isset($old[0]) ? $old[0]->skip : array();
498
+			foreach ($token as $object) {
499
+				$object->skip = $oldskip;
500
+				$object->skip[$injector] = true;
501
+			}
502
+		}
503
+
504
+	}
505
+
506
+	/**
507
+	 * Inserts a token before the current token. Cursor now points to
508
+	 * this token.  You must reprocess after this.
509
+	 */
510
+	private function insertBefore($token) {
511
+		array_splice($this->tokens, $this->t, 0, array($token));
512
+	}
513
+
514
+	/**
515
+	 * Removes current token. Cursor now points to new token occupying previously
516
+	 * occupied space.  You must reprocess after this.
517
+	 */
518
+	private function remove() {
519
+		array_splice($this->tokens, $this->t, 1);
520
+	}
521
+
522
+	/**
523
+	 * Swap current token with new token. Cursor points to new token (no
524
+	 * change).  You must reprocess after this.
525
+	 */
526
+	private function swap($token) {
527
+		$this->tokens[$this->t] = $token;
528
+	}
529 529
 
530 530
 }
531 531
 
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -65,17 +65,17 @@
 block discarded – undo
65 65
         $stack = array();
66 66
 
67 67
         // member variables
68
-        $this->stack   =& $stack;
69
-        $this->t       =& $t;
70
-        $this->tokens  =& $tokens;
68
+        $this->stack   = & $stack;
69
+        $this->t       = & $t;
70
+        $this->tokens  = & $tokens;
71 71
         $this->config  = $config;
72 72
         $this->context = $context;
73 73
 
74 74
         // context variables
75 75
         $context->register('CurrentNesting', $stack);
76
-        $context->register('InputIndex',     $t);
77
-        $context->register('InputTokens',    $tokens);
78
-        $context->register('CurrentToken',   $token);
76
+        $context->register('InputIndex', $t);
77
+        $context->register('InputTokens', $tokens);
78
+        $context->register('CurrentToken', $token);
79 79
 
80 80
         // -- begin INJECTOR --
81 81
 
Please login to merge, or discard this patch.
Braces   +71 added lines, -24 removed lines patch added patch discarded remove patch
@@ -87,9 +87,13 @@  discard block
 block discarded – undo
87 87
         unset($injectors['Custom']); // special case
88 88
         foreach ($injectors as $injector => $b) {
89 89
             // XXX: Fix with a legitimate lookup table of enabled filters
90
-            if (strpos($injector, '.') !== false) continue;
90
+            if (strpos($injector, '.') !== false) {
91
+            	continue;
92
+            }
91 93
             $injector = "HTMLPurifier_Injector_$injector";
92
-            if (!$b) continue;
94
+            if (!$b) {
95
+            	continue;
96
+            }
93 97
             $this->injectors[] = new $injector;
94 98
         }
95 99
         foreach ($def_injectors as $injector) {
@@ -97,7 +101,9 @@  discard block
 block discarded – undo
97 101
             $this->injectors[] = $injector;
98 102
         }
99 103
         foreach ($custom_injectors as $injector) {
100
-            if (!$injector) continue;
104
+            if (!$injector) {
105
+            	continue;
106
+            }
101 107
             if (is_string($injector)) {
102 108
                 $injector = "HTMLPurifier_Injector_$injector";
103 109
                 $injector = new $injector;
@@ -109,7 +115,9 @@  discard block
 block discarded – undo
109 115
         // variables for performance reasons
110 116
         foreach ($this->injectors as $ix => $injector) {
111 117
             $error = $injector->prepare($config, $context);
112
-            if (!$error) continue;
118
+            if (!$error) {
119
+            	continue;
120
+            }
113 121
             array_splice($this->injectors, $ix, 1); // rm the injector
114 122
             trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING);
115 123
         }
@@ -139,7 +147,9 @@  discard block
 block discarded – undo
139 147
                 // infinite loop, but might hinder some advanced rewinding.
140 148
                 $rewind_to = $this->injectors[$i]->getRewind();
141 149
                 if (is_int($rewind_to) && $rewind_to < $t) {
142
-                    if ($rewind_to < 0) $rewind_to = 0;
150
+                    if ($rewind_to < 0) {
151
+                    	$rewind_to = 0;
152
+                    }
143 153
                     while ($t > $rewind_to) {
144 154
                         $t--;
145 155
                         $prev = $tokens[$t];
@@ -147,8 +157,11 @@  discard block
 block discarded – undo
147 157
                         // but we need to reprocess it
148 158
                         unset($prev->skip[$i]);
149 159
                         $prev->rewind = $i;
150
-                        if ($prev instanceof HTMLPurifier_Token_Start) array_pop($this->stack);
151
-                        elseif ($prev instanceof HTMLPurifier_Token_End) $this->stack[] = $prev->start;
160
+                        if ($prev instanceof HTMLPurifier_Token_Start) {
161
+                        	array_pop($this->stack);
162
+                        } elseif ($prev instanceof HTMLPurifier_Token_End) {
163
+                        	$this->stack[] = $prev->start;
164
+                        }
152 165
                     }
153 166
                 }
154 167
                 $i = false;
@@ -157,7 +170,9 @@  discard block
 block discarded – undo
157 170
             // handle case of document end
158 171
             if (!isset($tokens[$t])) {
159 172
                 // kill processing if stack is empty
160
-                if (empty($this->stack)) break;
173
+                if (empty($this->stack)) {
174
+                	break;
175
+                }
161 176
 
162 177
                 // peek
163 178
                 $top_nesting = array_pop($this->stack);
@@ -185,8 +200,12 @@  discard block
 block discarded – undo
185 200
             if (empty($token->is_tag)) {
186 201
                 if ($token instanceof HTMLPurifier_Token_Text) {
187 202
                     foreach ($this->injectors as $i => $injector) {
188
-                        if (isset($token->skip[$i])) continue;
189
-                        if ($token->rewind !== null && $token->rewind !== $i) continue;
203
+                        if (isset($token->skip[$i])) {
204
+                        	continue;
205
+                        }
206
+                        if ($token->rewind !== null && $token->rewind !== $i) {
207
+                        	continue;
208
+                        }
190 209
                         $injector->handleText($token);
191 210
                         $this->processToken($token, $i);
192 211
                         $reprocess = true;
@@ -325,8 +344,12 @@  discard block
 block discarded – undo
325 344
 
326 345
             if ($ok) {
327 346
                 foreach ($this->injectors as $i => $injector) {
328
-                    if (isset($token->skip[$i])) continue;
329
-                    if ($token->rewind !== null && $token->rewind !== $i) continue;
347
+                    if (isset($token->skip[$i])) {
348
+                    	continue;
349
+                    }
350
+                    if ($token->rewind !== null && $token->rewind !== $i) {
351
+                    	continue;
352
+                    }
330 353
                     $injector->handleElement($token);
331 354
                     $this->processToken($token, $i);
332 355
                     $reprocess = true;
@@ -352,13 +375,17 @@  discard block
 block discarded – undo
352 375
             // make sure that we have something open
353 376
             if (empty($this->stack)) {
354 377
                 if ($escape_invalid_tags) {
355
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text');
378
+                    if ($e) {
379
+                    	$e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text');
380
+                    }
356 381
                     $this->swap(new HTMLPurifier_Token_Text(
357 382
                         $generator->generateFromToken($token)
358 383
                     ));
359 384
                 } else {
360 385
                     $this->remove();
361
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed');
386
+                    if ($e) {
387
+                    	$e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed');
388
+                    }
362 389
                 }
363 390
                 $reprocess = true;
364 391
                 continue;
@@ -372,8 +399,12 @@  discard block
 block discarded – undo
372 399
             if ($current_parent->name == $token->name) {
373 400
                 $token->start = $current_parent;
374 401
                 foreach ($this->injectors as $i => $injector) {
375
-                    if (isset($token->skip[$i])) continue;
376
-                    if ($token->rewind !== null && $token->rewind !== $i) continue;
402
+                    if (isset($token->skip[$i])) {
403
+                    	continue;
404
+                    }
405
+                    if ($token->rewind !== null && $token->rewind !== $i) {
406
+                    	continue;
407
+                    }
377 408
                     $injector->handleEnd($token);
378 409
                     $this->processToken($token, $i);
379 410
                     $this->stack[] = $current_parent;
@@ -406,10 +437,14 @@  discard block
 block discarded – undo
406 437
                     $this->swap(new HTMLPurifier_Token_Text(
407 438
                         $generator->generateFromToken($token)
408 439
                     ));
409
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text');
440
+                    if ($e) {
441
+                    	$e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text');
442
+                    }
410 443
                 } else {
411 444
                     $this->remove();
412
-                    if ($e) $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed');
445
+                    if ($e) {
446
+                    	$e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed');
447
+                    }
413 448
                 }
414 449
                 $reprocess = true;
415 450
                 continue;
@@ -479,12 +514,24 @@  discard block
 block discarded – undo
479 514
     protected function processToken($token, $injector = -1) {
480 515
 
481 516
         // normalize forms of token
482
-        if (is_object($token)) $token = array(1, $token);
483
-        if (is_int($token))    $token = array($token);
484
-        if ($token === false)  $token = array(1);
485
-        if (!is_array($token)) throw new HTMLPurifier_Exception('Invalid token type from injector');
486
-        if (!is_int($token[0])) array_unshift($token, 1);
487
-        if ($token[0] === 0) throw new HTMLPurifier_Exception('Deleting zero tokens is not valid');
517
+        if (is_object($token)) {
518
+        	$token = array(1, $token);
519
+        }
520
+        if (is_int($token)) {
521
+        	$token = array($token);
522
+        }
523
+        if ($token === false) {
524
+        	$token = array(1);
525
+        }
526
+        if (!is_array($token)) {
527
+        	throw new HTMLPurifier_Exception('Invalid token type from injector');
528
+        }
529
+        if (!is_int($token[0])) {
530
+        	array_unshift($token, 1);
531
+        }
532
+        if ($token[0] === 0) {
533
+        	throw new HTMLPurifier_Exception('Deleting zero tokens is not valid');
534
+        }
488 535
 
489 536
         // $token is now an array with the following form:
490 537
         // array(number nodes to delete, new node 1, new node 2, ...)
Please login to merge, or discard this patch.
htmlpurifier/library/HTMLPurifier/Strategy/RemoveForeignElements.php 3 patches
Indentation   +171 added lines, -171 removed lines patch added patch discarded remove patch
@@ -11,177 +11,177 @@
 block discarded – undo
11 11
 class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy
12 12
 {
13 13
 
14
-    public function execute($tokens, $config, $context) {
15
-        $definition = $config->getHTMLDefinition();
16
-        $generator = new HTMLPurifier_Generator($config, $context);
17
-        $result = array();
18
-
19
-        $escape_invalid_tags = $config->get('Core.EscapeInvalidTags');
20
-        $remove_invalid_img  = $config->get('Core.RemoveInvalidImg');
21
-
22
-        // currently only used to determine if comments should be kept
23
-        $trusted = $config->get('HTML.Trusted');
24
-        $comment_lookup = $config->get('HTML.AllowedComments');
25
-        $comment_regexp = $config->get('HTML.AllowedCommentsRegexp');
26
-        $check_comments = $comment_lookup !== array() || $comment_regexp !== null;
27
-
28
-        $remove_script_contents = $config->get('Core.RemoveScriptContents');
29
-        $hidden_elements     = $config->get('Core.HiddenElements');
30
-
31
-        // remove script contents compatibility
32
-        if ($remove_script_contents === true) {
33
-            $hidden_elements['script'] = true;
34
-        } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) {
35
-            unset($hidden_elements['script']);
36
-        }
37
-
38
-        $attr_validator = new HTMLPurifier_AttrValidator();
39
-
40
-        // removes tokens until it reaches a closing tag with its value
41
-        $remove_until = false;
42
-
43
-        // converts comments into text tokens when this is equal to a tag name
44
-        $textify_comments = false;
45
-
46
-        $token = false;
47
-        $context->register('CurrentToken', $token);
48
-
49
-        $e = false;
50
-        if ($config->get('Core.CollectErrors')) {
51
-            $e =& $context->get('ErrorCollector');
52
-        }
53
-
54
-        foreach($tokens as $token) {
55
-            if ($remove_until) {
56
-                if (empty($token->is_tag) || $token->name !== $remove_until) {
57
-                    continue;
58
-                }
59
-            }
60
-            if (!empty( $token->is_tag )) {
61
-                // DEFINITION CALL
62
-
63
-                // before any processing, try to transform the element
64
-                if (
65
-                    isset($definition->info_tag_transform[$token->name])
66
-                ) {
67
-                    $original_name = $token->name;
68
-                    // there is a transformation for this tag
69
-                    // DEFINITION CALL
70
-                    $token = $definition->
71
-                                info_tag_transform[$token->name]->
72
-                                    transform($token, $config, $context);
73
-                    if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name);
74
-                }
75
-
76
-                if (isset($definition->info[$token->name])) {
77
-
78
-                    // mostly everything's good, but
79
-                    // we need to make sure required attributes are in order
80
-                    if (
81
-                        ($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) &&
82
-                        $definition->info[$token->name]->required_attr &&
83
-                        ($token->name != 'img' || $remove_invalid_img) // ensure config option still works
84
-                    ) {
85
-                        $attr_validator->validateToken($token, $config, $context);
86
-                        $ok = true;
87
-                        foreach ($definition->info[$token->name]->required_attr as $name) {
88
-                            if (!isset($token->attr[$name])) {
89
-                                $ok = false;
90
-                                break;
91
-                            }
92
-                        }
93
-                        if (!$ok) {
94
-                            if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name);
95
-                            continue;
96
-                        }
97
-                        $token->armor['ValidateAttributes'] = true;
98
-                    }
99
-
100
-                    if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) {
101
-                        $textify_comments = $token->name;
102
-                    } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) {
103
-                        $textify_comments = false;
104
-                    }
105
-
106
-                } elseif ($escape_invalid_tags) {
107
-                    // invalid tag, generate HTML representation and insert in
108
-                    if ($e) $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text');
109
-                    $token = new HTMLPurifier_Token_Text(
110
-                        $generator->generateFromToken($token)
111
-                    );
112
-                } else {
113
-                    // check if we need to destroy all of the tag's children
114
-                    // CAN BE GENERICIZED
115
-                    if (isset($hidden_elements[$token->name])) {
116
-                        if ($token instanceof HTMLPurifier_Token_Start) {
117
-                            $remove_until = $token->name;
118
-                        } elseif ($token instanceof HTMLPurifier_Token_Empty) {
119
-                            // do nothing: we're still looking
120
-                        } else {
121
-                            $remove_until = false;
122
-                        }
123
-                        if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed');
124
-                    } else {
125
-                        if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed');
126
-                    }
127
-                    continue;
128
-                }
129
-            } elseif ($token instanceof HTMLPurifier_Token_Comment) {
130
-                // textify comments in script tags when they are allowed
131
-                if ($textify_comments !== false) {
132
-                    $data = $token->data;
133
-                    $token = new HTMLPurifier_Token_Text($data);
134
-                } elseif ($trusted || $check_comments) {
135
-                    // always cleanup comments
136
-                    $trailing_hyphen = false;
137
-                    if ($e) {
138
-                        // perform check whether or not there's a trailing hyphen
139
-                        if (substr($token->data, -1) == '-') {
140
-                            $trailing_hyphen = true;
141
-                        }
142
-                    }
143
-                    $token->data = rtrim($token->data, '-');
144
-                    $found_double_hyphen = false;
145
-                    while (strpos($token->data, '--') !== false) {
146
-                        $found_double_hyphen = true;
147
-                        $token->data = str_replace('--', '-', $token->data);
148
-                    }
149
-                    if ($trusted || !empty($comment_lookup[trim($token->data)]) || ($comment_regexp !== NULL && preg_match($comment_regexp, trim($token->data)))) {
150
-                        // OK good
151
-                        if ($e) {
152
-                            if ($trailing_hyphen) {
153
-                                $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed');
154
-                            }
155
-                            if ($found_double_hyphen) {
156
-                                $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed');
157
-                            }
158
-                        }
159
-                    } else {
160
-                        if ($e) {
161
-                            $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
162
-                        }
163
-                        continue;
164
-                    }
165
-                } else {
166
-                    // strip comments
167
-                    if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
168
-                    continue;
169
-                }
170
-            } elseif ($token instanceof HTMLPurifier_Token_Text) {
171
-            } else {
172
-                continue;
173
-            }
174
-            $result[] = $token;
175
-        }
176
-        if ($remove_until && $e) {
177
-            // we removed tokens until the end, throw error
178
-            $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until);
179
-        }
180
-
181
-        $context->destroy('CurrentToken');
182
-
183
-        return $result;
184
-    }
14
+	public function execute($tokens, $config, $context) {
15
+		$definition = $config->getHTMLDefinition();
16
+		$generator = new HTMLPurifier_Generator($config, $context);
17
+		$result = array();
18
+
19
+		$escape_invalid_tags = $config->get('Core.EscapeInvalidTags');
20
+		$remove_invalid_img  = $config->get('Core.RemoveInvalidImg');
21
+
22
+		// currently only used to determine if comments should be kept
23
+		$trusted = $config->get('HTML.Trusted');
24
+		$comment_lookup = $config->get('HTML.AllowedComments');
25
+		$comment_regexp = $config->get('HTML.AllowedCommentsRegexp');
26
+		$check_comments = $comment_lookup !== array() || $comment_regexp !== null;
27
+
28
+		$remove_script_contents = $config->get('Core.RemoveScriptContents');
29
+		$hidden_elements     = $config->get('Core.HiddenElements');
30
+
31
+		// remove script contents compatibility
32
+		if ($remove_script_contents === true) {
33
+			$hidden_elements['script'] = true;
34
+		} elseif ($remove_script_contents === false && isset($hidden_elements['script'])) {
35
+			unset($hidden_elements['script']);
36
+		}
37
+
38
+		$attr_validator = new HTMLPurifier_AttrValidator();
39
+
40
+		// removes tokens until it reaches a closing tag with its value
41
+		$remove_until = false;
42
+
43
+		// converts comments into text tokens when this is equal to a tag name
44
+		$textify_comments = false;
45
+
46
+		$token = false;
47
+		$context->register('CurrentToken', $token);
48
+
49
+		$e = false;
50
+		if ($config->get('Core.CollectErrors')) {
51
+			$e =& $context->get('ErrorCollector');
52
+		}
53
+
54
+		foreach($tokens as $token) {
55
+			if ($remove_until) {
56
+				if (empty($token->is_tag) || $token->name !== $remove_until) {
57
+					continue;
58
+				}
59
+			}
60
+			if (!empty( $token->is_tag )) {
61
+				// DEFINITION CALL
62
+
63
+				// before any processing, try to transform the element
64
+				if (
65
+					isset($definition->info_tag_transform[$token->name])
66
+				) {
67
+					$original_name = $token->name;
68
+					// there is a transformation for this tag
69
+					// DEFINITION CALL
70
+					$token = $definition->
71
+								info_tag_transform[$token->name]->
72
+									transform($token, $config, $context);
73
+					if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name);
74
+				}
75
+
76
+				if (isset($definition->info[$token->name])) {
77
+
78
+					// mostly everything's good, but
79
+					// we need to make sure required attributes are in order
80
+					if (
81
+						($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) &&
82
+						$definition->info[$token->name]->required_attr &&
83
+						($token->name != 'img' || $remove_invalid_img) // ensure config option still works
84
+					) {
85
+						$attr_validator->validateToken($token, $config, $context);
86
+						$ok = true;
87
+						foreach ($definition->info[$token->name]->required_attr as $name) {
88
+							if (!isset($token->attr[$name])) {
89
+								$ok = false;
90
+								break;
91
+							}
92
+						}
93
+						if (!$ok) {
94
+							if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name);
95
+							continue;
96
+						}
97
+						$token->armor['ValidateAttributes'] = true;
98
+					}
99
+
100
+					if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) {
101
+						$textify_comments = $token->name;
102
+					} elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) {
103
+						$textify_comments = false;
104
+					}
105
+
106
+				} elseif ($escape_invalid_tags) {
107
+					// invalid tag, generate HTML representation and insert in
108
+					if ($e) $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text');
109
+					$token = new HTMLPurifier_Token_Text(
110
+						$generator->generateFromToken($token)
111
+					);
112
+				} else {
113
+					// check if we need to destroy all of the tag's children
114
+					// CAN BE GENERICIZED
115
+					if (isset($hidden_elements[$token->name])) {
116
+						if ($token instanceof HTMLPurifier_Token_Start) {
117
+							$remove_until = $token->name;
118
+						} elseif ($token instanceof HTMLPurifier_Token_Empty) {
119
+							// do nothing: we're still looking
120
+						} else {
121
+							$remove_until = false;
122
+						}
123
+						if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed');
124
+					} else {
125
+						if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed');
126
+					}
127
+					continue;
128
+				}
129
+			} elseif ($token instanceof HTMLPurifier_Token_Comment) {
130
+				// textify comments in script tags when they are allowed
131
+				if ($textify_comments !== false) {
132
+					$data = $token->data;
133
+					$token = new HTMLPurifier_Token_Text($data);
134
+				} elseif ($trusted || $check_comments) {
135
+					// always cleanup comments
136
+					$trailing_hyphen = false;
137
+					if ($e) {
138
+						// perform check whether or not there's a trailing hyphen
139
+						if (substr($token->data, -1) == '-') {
140
+							$trailing_hyphen = true;
141
+						}
142
+					}
143
+					$token->data = rtrim($token->data, '-');
144
+					$found_double_hyphen = false;
145
+					while (strpos($token->data, '--') !== false) {
146
+						$found_double_hyphen = true;
147
+						$token->data = str_replace('--', '-', $token->data);
148
+					}
149
+					if ($trusted || !empty($comment_lookup[trim($token->data)]) || ($comment_regexp !== NULL && preg_match($comment_regexp, trim($token->data)))) {
150
+						// OK good
151
+						if ($e) {
152
+							if ($trailing_hyphen) {
153
+								$e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed');
154
+							}
155
+							if ($found_double_hyphen) {
156
+								$e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed');
157
+							}
158
+						}
159
+					} else {
160
+						if ($e) {
161
+							$e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
162
+						}
163
+						continue;
164
+					}
165
+				} else {
166
+					// strip comments
167
+					if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
168
+					continue;
169
+				}
170
+			} elseif ($token instanceof HTMLPurifier_Token_Text) {
171
+			} else {
172
+				continue;
173
+			}
174
+			$result[] = $token;
175
+		}
176
+		if ($remove_until && $e) {
177
+			// we removed tokens until the end, throw error
178
+			$e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until);
179
+		}
180
+
181
+		$context->destroy('CurrentToken');
182
+
183
+		return $result;
184
+	}
185 185
 
186 186
 }
187 187
 
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
         $check_comments = $comment_lookup !== array() || $comment_regexp !== null;
27 27
 
28 28
         $remove_script_contents = $config->get('Core.RemoveScriptContents');
29
-        $hidden_elements     = $config->get('Core.HiddenElements');
29
+        $hidden_elements = $config->get('Core.HiddenElements');
30 30
 
31 31
         // remove script contents compatibility
32 32
         if ($remove_script_contents === true) {
@@ -48,16 +48,16 @@  discard block
 block discarded – undo
48 48
 
49 49
         $e = false;
50 50
         if ($config->get('Core.CollectErrors')) {
51
-            $e =& $context->get('ErrorCollector');
51
+            $e = & $context->get('ErrorCollector');
52 52
         }
53 53
 
54
-        foreach($tokens as $token) {
54
+        foreach ($tokens as $token) {
55 55
             if ($remove_until) {
56 56
                 if (empty($token->is_tag) || $token->name !== $remove_until) {
57 57
                     continue;
58 58
                 }
59 59
             }
60
-            if (!empty( $token->is_tag )) {
60
+            if (!empty($token->is_tag)) {
61 61
                 // DEFINITION CALL
62 62
 
63 63
                 // before any processing, try to transform the element
Please login to merge, or discard this patch.
Braces   +18 added lines, -6 removed lines patch added patch discarded remove patch
@@ -70,7 +70,9 @@  discard block
 block discarded – undo
70 70
                     $token = $definition->
71 71
                                 info_tag_transform[$token->name]->
72 72
                                     transform($token, $config, $context);
73
-                    if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name);
73
+                    if ($e) {
74
+                    	$e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name);
75
+                    }
74 76
                 }
75 77
 
76 78
                 if (isset($definition->info[$token->name])) {
@@ -91,7 +93,9 @@  discard block
 block discarded – undo
91 93
                             }
92 94
                         }
93 95
                         if (!$ok) {
94
-                            if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name);
96
+                            if ($e) {
97
+                            	$e->send(E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name);
98
+                            }
95 99
                             continue;
96 100
                         }
97 101
                         $token->armor['ValidateAttributes'] = true;
@@ -105,7 +109,9 @@  discard block
 block discarded – undo
105 109
 
106 110
                 } elseif ($escape_invalid_tags) {
107 111
                     // invalid tag, generate HTML representation and insert in
108
-                    if ($e) $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text');
112
+                    if ($e) {
113
+                    	$e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text');
114
+                    }
109 115
                     $token = new HTMLPurifier_Token_Text(
110 116
                         $generator->generateFromToken($token)
111 117
                     );
@@ -120,9 +126,13 @@  discard block
 block discarded – undo
120 126
                         } else {
121 127
                             $remove_until = false;
122 128
                         }
123
-                        if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed');
129
+                        if ($e) {
130
+                        	$e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed');
131
+                        }
124 132
                     } else {
125
-                        if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed');
133
+                        if ($e) {
134
+                        	$e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed');
135
+                        }
126 136
                     }
127 137
                     continue;
128 138
                 }
@@ -164,7 +174,9 @@  discard block
 block discarded – undo
164 174
                     }
165 175
                 } else {
166 176
                     // strip comments
167
-                    if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
177
+                    if ($e) {
178
+                    	$e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
179
+                    }
168 180
                     continue;
169 181
                 }
170 182
             } elseif ($token instanceof HTMLPurifier_Token_Text) {
Please login to merge, or discard this patch.
security/htmlpurifier/library/HTMLPurifier/Strategy/ValidateAttributes.php 2 patches
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -7,32 +7,32 @@
 block discarded – undo
7 7
 class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy
8 8
 {
9 9
 
10
-    public function execute($tokens, $config, $context) {
10
+	public function execute($tokens, $config, $context) {
11 11
 
12
-        // setup validator
13
-        $validator = new HTMLPurifier_AttrValidator();
12
+		// setup validator
13
+		$validator = new HTMLPurifier_AttrValidator();
14 14
 
15
-        $token = false;
16
-        $context->register('CurrentToken', $token);
15
+		$token = false;
16
+		$context->register('CurrentToken', $token);
17 17
 
18
-        foreach ($tokens as $key => $token) {
18
+		foreach ($tokens as $key => $token) {
19 19
 
20
-            // only process tokens that have attributes,
21
-            //   namely start and empty tags
22
-            if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) continue;
20
+			// only process tokens that have attributes,
21
+			//   namely start and empty tags
22
+			if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) continue;
23 23
 
24
-            // skip tokens that are armored
25
-            if (!empty($token->armor['ValidateAttributes'])) continue;
24
+			// skip tokens that are armored
25
+			if (!empty($token->armor['ValidateAttributes'])) continue;
26 26
 
27
-            // note that we have no facilities here for removing tokens
28
-            $validator->validateToken($token, $config, $context);
27
+			// note that we have no facilities here for removing tokens
28
+			$validator->validateToken($token, $config, $context);
29 29
 
30
-            $tokens[$key] = $token; // for PHP 4
31
-        }
32
-        $context->destroy('CurrentToken');
30
+			$tokens[$key] = $token; // for PHP 4
31
+		}
32
+		$context->destroy('CurrentToken');
33 33
 
34
-        return $tokens;
35
-    }
34
+		return $tokens;
35
+	}
36 36
 
37 37
 }
38 38
 
Please login to merge, or discard this patch.
Braces   +6 added lines, -2 removed lines patch added patch discarded remove patch
@@ -19,10 +19,14 @@
 block discarded – undo
19 19
 
20 20
             // only process tokens that have attributes,
21 21
             //   namely start and empty tags
22
-            if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) continue;
22
+            if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) {
23
+            	continue;
24
+            }
23 25
 
24 26
             // skip tokens that are armored
25
-            if (!empty($token->armor['ValidateAttributes'])) continue;
27
+            if (!empty($token->armor['ValidateAttributes'])) {
28
+            	continue;
29
+            }
26 30
 
27 31
             // note that we have no facilities here for removing tokens
28 32
             $validator->validateToken($token, $config, $context);
Please login to merge, or discard this patch.