]> git.mxchange.org Git - friendica.git/blob - library/HTMLPurifier/Strategy/RemoveForeignElements.php
make 'PHP "register_argc_argv"' easier to translate, may require fix for po2php
[friendica.git] / library / HTMLPurifier / Strategy / RemoveForeignElements.php
1 <?php
2
3 /**
4  * Removes all unrecognized tags from the list of tokens.
5  *
6  * This strategy iterates through all the tokens and removes unrecognized
7  * tokens. If a token is not recognized but a TagTransform is defined for
8  * that element, the element will be transformed accordingly.
9  */
10
11 class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy
12 {
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
25         $remove_script_contents = $config->get('Core.RemoveScriptContents');
26         $hidden_elements     = $config->get('Core.HiddenElements');
27
28         // remove script contents compatibility
29         if ($remove_script_contents === true) {
30             $hidden_elements['script'] = true;
31         } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) {
32             unset($hidden_elements['script']);
33         }
34
35         $attr_validator = new HTMLPurifier_AttrValidator();
36
37         // removes tokens until it reaches a closing tag with its value
38         $remove_until = false;
39
40         // converts comments into text tokens when this is equal to a tag name
41         $textify_comments = false;
42
43         $token = false;
44         $context->register('CurrentToken', $token);
45
46         $e = false;
47         if ($config->get('Core.CollectErrors')) {
48             $e =& $context->get('ErrorCollector');
49         }
50
51         foreach($tokens as $token) {
52             if ($remove_until) {
53                 if (empty($token->is_tag) || $token->name !== $remove_until) {
54                     continue;
55                 }
56             }
57             if (!empty( $token->is_tag )) {
58                 // DEFINITION CALL
59
60                 // before any processing, try to transform the element
61                 if (
62                     isset($definition->info_tag_transform[$token->name])
63                 ) {
64                     $original_name = $token->name;
65                     // there is a transformation for this tag
66                     // DEFINITION CALL
67                     $token = $definition->
68                                 info_tag_transform[$token->name]->
69                                     transform($token, $config, $context);
70                     if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name);
71                 }
72
73                 if (isset($definition->info[$token->name])) {
74
75                     // mostly everything's good, but
76                     // we need to make sure required attributes are in order
77                     if (
78                         ($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) &&
79                         $definition->info[$token->name]->required_attr &&
80                         ($token->name != 'img' || $remove_invalid_img) // ensure config option still works
81                     ) {
82                         $attr_validator->validateToken($token, $config, $context);
83                         $ok = true;
84                         foreach ($definition->info[$token->name]->required_attr as $name) {
85                             if (!isset($token->attr[$name])) {
86                                 $ok = false;
87                                 break;
88                             }
89                         }
90                         if (!$ok) {
91                             if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Missing required attribute', $name);
92                             continue;
93                         }
94                         $token->armor['ValidateAttributes'] = true;
95                     }
96
97                     if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) {
98                         $textify_comments = $token->name;
99                     } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) {
100                         $textify_comments = false;
101                     }
102
103                 } elseif ($escape_invalid_tags) {
104                     // invalid tag, generate HTML representation and insert in
105                     if ($e) $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text');
106                     $token = new HTMLPurifier_Token_Text(
107                         $generator->generateFromToken($token)
108                     );
109                 } else {
110                     // check if we need to destroy all of the tag's children
111                     // CAN BE GENERICIZED
112                     if (isset($hidden_elements[$token->name])) {
113                         if ($token instanceof HTMLPurifier_Token_Start) {
114                             $remove_until = $token->name;
115                         } elseif ($token instanceof HTMLPurifier_Token_Empty) {
116                             // do nothing: we're still looking
117                         } else {
118                             $remove_until = false;
119                         }
120                         if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed');
121                     } else {
122                         if ($e) $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed');
123                     }
124                     continue;
125                 }
126             } elseif ($token instanceof HTMLPurifier_Token_Comment) {
127                 // textify comments in script tags when they are allowed
128                 if ($textify_comments !== false) {
129                     $data = $token->data;
130                     $token = new HTMLPurifier_Token_Text($data);
131                 } elseif ($trusted) {
132                     // keep, but perform comment cleaning
133                     if ($e) {
134                         // perform check whether or not there's a trailing hyphen
135                         if (substr($token->data, -1) == '-') {
136                             $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed');
137                         }
138                     }
139                     $token->data = rtrim($token->data, '-');
140                     $found_double_hyphen = false;
141                     while (strpos($token->data, '--') !== false) {
142                         if ($e && !$found_double_hyphen) {
143                             $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed');
144                         }
145                         $found_double_hyphen = true; // prevent double-erroring
146                         $token->data = str_replace('--', '-', $token->data);
147                     }
148                 } else {
149                     // strip comments
150                     if ($e) $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed');
151                     continue;
152                 }
153             } elseif ($token instanceof HTMLPurifier_Token_Text) {
154             } else {
155                 continue;
156             }
157             $result[] = $token;
158         }
159         if ($remove_until && $e) {
160             // we removed tokens until the end, throw error
161             $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until);
162         }
163
164         $context->destroy('CurrentToken');
165
166         return $result;
167     }
168
169 }
170
171 // vim: et sw=4 sts=4