HTMLPurifier/ConfigSchema/Validator.php Quellcode

Validator.php
gehe zur Dokumentation dieser Datei
1 <?php
2 
12 {
13 
17  protected $interchange;
18 
22  protected $aliases;
23 
28  protected $context = array();
29 
34  protected $parser;
35 
36  public function __construct()
37  {
38  $this->parser = new HTMLPurifier_VarParser();
39  }
40 
46  public function validate($interchange)
47  {
48  $this->interchange = $interchange;
49  $this->aliases = array();
50  // PHP is a bit lax with integer <=> string conversions in
51  // arrays, so we don't use the identical !== comparison
52  foreach ($interchange->directives as $i => $directive) {
53  $id = $directive->id->toString();
54  if ($i != $id) {
55  $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'");
56  }
57  $this->validateDirective($directive);
58  }
59  return true;
60  }
61 
66  public function validateId($id)
67  {
68  $id_string = $id->toString();
69  $this->context[] = "id '$id_string'";
70  if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) {
71  // handled by InterchangeBuilder
72  $this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id');
73  }
74  // keys are now unconstrained (we might want to narrow down to A-Za-z0-9.)
75  // we probably should check that it has at least one namespace
76  $this->with($id, 'key')
77  ->assertNotEmpty()
78  ->assertIsString(); // implicit assertIsString handled by InterchangeBuilder
79  array_pop($this->context);
80  }
81 
86  public function validateDirective($d)
87  {
88  $id = $d->id->toString();
89  $this->context[] = "directive '$id'";
90  $this->validateId($d->id);
91 
92  $this->with($d, 'description')
93  ->assertNotEmpty();
94 
95  // BEGIN - handled by InterchangeBuilder
96  $this->with($d, 'type')
97  ->assertNotEmpty();
98  $this->with($d, 'typeAllowsNull')
99  ->assertIsBool();
100  try {
101  // This also tests validity of $d->type
102  $this->parser->parse($d->default, $d->type, $d->typeAllowsNull);
103  } catch (HTMLPurifier_VarParserException $e) {
104  $this->error('default', 'had error: ' . $e->getMessage());
105  }
106  // END - handled by InterchangeBuilder
107 
108  if (!is_null($d->allowed) || !empty($d->valueAliases)) {
109  // allowed and valueAliases require that we be dealing with
110  // strings, so check for that early.
111  $d_int = HTMLPurifier_VarParser::$types[$d->type];
112  if (!isset(HTMLPurifier_VarParser::$stringTypes[$d_int])) {
113  $this->error('type', 'must be a string type when used with allowed or value aliases');
114  }
115  }
116 
117  $this->validateDirectiveAllowed($d);
119  $this->validateDirectiveAliases($d);
120 
121  array_pop($this->context);
122  }
123 
129  public function validateDirectiveAllowed($d)
130  {
131  if (is_null($d->allowed)) {
132  return;
133  }
134  $this->with($d, 'allowed')
135  ->assertNotEmpty()
136  ->assertIsLookup(); // handled by InterchangeBuilder
137  if (is_string($d->default) && !isset($d->allowed[$d->default])) {
138  $this->error('default', 'must be an allowed value');
139  }
140  $this->context[] = 'allowed';
141  foreach ($d->allowed as $val => $x) {
142  if (!is_string($val)) {
143  $this->error("value $val", 'must be a string');
144  }
145  }
146  array_pop($this->context);
147  }
148 
154  public function validateDirectiveValueAliases($d)
155  {
156  if (is_null($d->valueAliases)) {
157  return;
158  }
159  $this->with($d, 'valueAliases')
160  ->assertIsArray(); // handled by InterchangeBuilder
161  $this->context[] = 'valueAliases';
162  foreach ($d->valueAliases as $alias => $real) {
163  if (!is_string($alias)) {
164  $this->error("alias $alias", 'must be a string');
165  }
166  if (!is_string($real)) {
167  $this->error("alias target $real from alias '$alias'", 'must be a string');
168  }
169  if ($alias === $real) {
170  $this->error("alias '$alias'", "must not be an alias to itself");
171  }
172  }
173  if (!is_null($d->allowed)) {
174  foreach ($d->valueAliases as $alias => $real) {
175  if (isset($d->allowed[$alias])) {
176  $this->error("alias '$alias'", 'must not be an allowed value');
177  } elseif (!isset($d->allowed[$real])) {
178  $this->error("alias '$alias'", 'must be an alias to an allowed value');
179  }
180  }
181  }
182  array_pop($this->context);
183  }
184 
190  public function validateDirectiveAliases($d)
191  {
192  $this->with($d, 'aliases')
193  ->assertIsArray(); // handled by InterchangeBuilder
194  $this->context[] = 'aliases';
195  foreach ($d->aliases as $alias) {
196  $this->validateId($alias);
197  $s = $alias->toString();
198  if (isset($this->interchange->directives[$s])) {
199  $this->error("alias '$s'", 'collides with another directive');
200  }
201  if (isset($this->aliases[$s])) {
202  $other_directive = $this->aliases[$s];
203  $this->error("alias '$s'", "collides with alias for directive '$other_directive'");
204  }
205  $this->aliases[$s] = $d->id->toString();
206  }
207  array_pop($this->context);
208  }
209 
210  // protected helper functions
211 
219  protected function with($obj, $member)
220  {
221  return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member);
222  }
223 
228  protected function error($target, $msg)
229  {
230  if ($target !== false) {
231  $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext();
232  } else {
233  $prefix = ucfirst($this->getFormattedContext());
234  }
235  throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg));
236  }
237 
242  protected function getFormattedContext()
243  {
244  return implode(' in ', array_reverse($this->context));
245  }
246 }
247 
248 // vim: et sw=4 sts=4




Korrekturen, Hinweise und Ergänzungen

Bitte scheuen Sie sich nicht und melden Sie, was auf dieser Seite sachlich falsch oder irreführend ist, was ergänzt werden sollte, was fehlt usw. Dazu bitte oben aus dem Menü Seite den Eintrag Support Forum wählen. Es ist eine kostenlose Anmeldung erforderlich, um Anmerkungen zu posten. Unpassende Postings, Spam usw. werden kommentarlos entfernt.