diff --git a/library/HTMLPurifier.php b/library/HTMLPurifier.php index e9e8219b..7203800d 100644 --- a/library/HTMLPurifier.php +++ b/library/HTMLPurifier.php @@ -147,7 +147,7 @@ class HTMLPurifier $language = $language_factory->create($config->get('Core', 'Language')); $context->register('Locale', $language); - $error_collector = new HTMLPurifier_ErrorCollector($language); + $error_collector = new HTMLPurifier_ErrorCollector($context); $context->register('ErrorCollector', $error_collector); } diff --git a/library/HTMLPurifier/Context.php b/library/HTMLPurifier/Context.php index c5ad8236..6420cdcb 100644 --- a/library/HTMLPurifier/Context.php +++ b/library/HTMLPurifier/Context.php @@ -31,11 +31,14 @@ class HTMLPurifier_Context /** * Retrieves a variable reference from the context. * @param $name String name + * @param $ignore_error Boolean whether or not to ignore error */ - function &get($name) { + function &get($name, $ignore_error = false) { if (!isset($this->_storage[$name])) { - trigger_error("Attempted to retrieve non-existent variable $name", - E_USER_ERROR); + if (!$ignore_error) { + trigger_error("Attempted to retrieve non-existent variable $name", + E_USER_ERROR); + } $var = null; // so we can return by reference return $var; } diff --git a/library/HTMLPurifier/ErrorCollector.php b/library/HTMLPurifier/ErrorCollector.php index 762c8dd6..0a249f7a 100644 --- a/library/HTMLPurifier/ErrorCollector.php +++ b/library/HTMLPurifier/ErrorCollector.php @@ -11,8 +11,12 @@ class HTMLPurifier_ErrorCollector var $errors = array(); var $locale; + var $context; - function HTMLPurifier_ErrorCollector(&$locale) {$this->locale =& $locale;} + function HTMLPurifier_ErrorCollector(&$context) { + $this->locale =& $context->get('Locale'); + $this->context =& $context; + } /** * Sends an error message to the collector for later use @@ -20,20 +24,23 @@ class HTMLPurifier_ErrorCollector * @param $severity int Error severity, PHP error style (don't use E_USER_) * @param $msg string Error message text */ - function send($line, $severity, $msg) { - $token = false; - if ($line && !is_int($line)) { - $token = $line; - $line = $token->line; - if (!$line) $line = false; - } - if (func_num_args() == 3) $msg = $this->locale->getMessage($msg); - else { - $args = func_get_args(); - array_splice($args, 0, 2); // one less to make 1-based - unset($args[0]); + function send($severity, $msg, $args = array()) { + if (func_num_args() == 2) { + $msg = $this->locale->getMessage($msg); + } else { + // setup one-based array if necessary + if (!is_array($args)) { + $args = func_get_args(); + array_shift($args); + unset($args[0]); + } $msg = $this->locale->formatMessage($msg, $args); } + + $line = $this->context->get('CurrentLine', true); + $token = $this->context->get('CurrentToken', true); + $attr = $this->context->get('CurrentAttr', true); + $this->errors[] = array($line, $severity, $msg); } diff --git a/library/HTMLPurifier/Lexer/DirectLex.php b/library/HTMLPurifier/Lexer/DirectLex.php index 1cdc1a64..89a66b24 100644 --- a/library/HTMLPurifier/Lexer/DirectLex.php +++ b/library/HTMLPurifier/Lexer/DirectLex.php @@ -138,7 +138,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer // uh oh, we have a comment that extends to // infinity. Can't be helped: set comment // end position to end of string - if ($e) $e->send($current_line, E_WARNING, 'Lexer: Unclosed comment'); + if ($e) $e->send(E_WARNING, 'Lexer: Unclosed comment'); $position_comment_end = strlen($html); $end = true; } else { @@ -181,7 +181,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer // have accidently grabbed an emoticon. Translate into // text and go our merry way if (!ctype_alnum($segment[0])) { - if ($e) $e->send($current_line, E_NOTICE, 'Lexer: Unescaped lt'); + if ($e) $e->send(E_NOTICE, 'Lexer: Unescaped lt'); $token = new HTMLPurifier_Token_Text( '<' . @@ -261,7 +261,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer continue; } else { // inside tag, but there's no ending > sign - if ($e) $e->send($current_line, E_WARNING, 'Lexer: Missing gt'); + if ($e) $e->send(E_WARNING, 'Lexer: Missing gt'); $token = new HTMLPurifier_Token_Text( '<' . @@ -327,7 +327,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer list($key, $quoted_value) = explode('=', $string); $quoted_value = trim($quoted_value); if (!$key) { - if ($e) $e->send($current_line, E_ERROR, 'Lexer: Missing attribute key'); + if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); return array(); } if (!$quoted_value) return array($key => ''); @@ -343,7 +343,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer } else { // not well behaved if ($open_quote) { - if ($e) $e->send($current_line, E_ERROR, 'Lexer: Missing end quote'); + if ($e) $e->send(E_ERROR, 'Lexer: Missing end quote'); $value = substr($quoted_value, 1); } else { $value = $quoted_value; @@ -390,7 +390,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer $key = substr($string, $key_begin, $key_end - $key_begin); if (!$key) { - if ($e) $e->send($current_line, E_ERROR, 'Lexer: Missing attribute key'); + if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); $cursor += strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop continue; // empty key } @@ -440,7 +440,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer $array[$key] = $key; } else { // purely theoretical - if ($e) $e->send($current_line, E_ERROR, 'Lexer: Missing attribute key'); + if ($e) $e->send(E_ERROR, 'Lexer: Missing attribute key'); } } diff --git a/tests/HTMLPurifier/ErrorCollectorTest.php b/tests/HTMLPurifier/ErrorCollectorTest.php index 95c0578e..ae84bfd2 100644 --- a/tests/HTMLPurifier/ErrorCollectorTest.php +++ b/tests/HTMLPurifier/ErrorCollectorTest.php @@ -11,9 +11,6 @@ class HTMLPurifier_ErrorCollectorTest extends UnitTestCase function test() { - $tok = new HTMLPurifier_Token_Start('a'); // also caused error - $tok->line = 3; - $language = new HTMLPurifier_LanguageMock(); $language->setReturnValue('getErrorName', 'Error', array(E_ERROR)); $language->setReturnValue('getErrorName', 'Warning', array(E_WARNING)); @@ -22,9 +19,19 @@ class HTMLPurifier_ErrorCollectorTest extends UnitTestCase $language->setReturnValue('formatMessage', ' at line 23', array('ErrorCollector: At line', array('line' => 23))); $language->setReturnValue('formatMessage', ' at line 3', array('ErrorCollector: At line', array('line' => 3))); - $collector = new HTMLPurifier_ErrorCollector($language); - $collector->send(23, E_ERROR, 'message-1'); - $collector->send($tok, E_WARNING, 'message-2', 'param'); + $line = false; + + $context = new HTMLPurifier_Context(); + $context->register('Locale', $language); + $context->register('CurrentLine', $line); + + $collector = new HTMLPurifier_ErrorCollector($context); + + $line = 23; + $collector->send(E_ERROR, 'message-1'); + + $line = 3; + $collector->send(E_WARNING, 'message-2', 'param'); $result = array( 0 => array(23, E_ERROR, 'Message 1'), @@ -46,25 +53,30 @@ class HTMLPurifier_ErrorCollectorTest extends UnitTestCase function testNoErrors() { $language = new HTMLPurifier_LanguageMock(); $language->setReturnValue('getMessage', 'No errors', array('ErrorCollector: No errors')); - $collector = new HTMLPurifier_ErrorCollector($language); + $context = new HTMLPurifier_Context(); + $context->register('Locale', $language); + + $collector = new HTMLPurifier_ErrorCollector($context); $formatted_result = '

No errors

'; $config = HTMLPurifier_Config::createDefault(); $this->assertIdentical($collector->getHTMLFormatted($config), $formatted_result); } function testNoLineNumbers() { - $token = new HTMLPurifier_Token_Start('a'); // no line number! $language = new HTMLPurifier_LanguageMock(); $language->setReturnValue('getMessage', 'Message 1', array('message-1')); $language->setReturnValue('getMessage', 'Message 2', array('message-2')); $language->setReturnValue('getErrorName', 'Error', array(E_ERROR)); - $collector = new HTMLPurifier_ErrorCollector($language); - $collector->send(false, E_ERROR, 'message-1'); - $collector->send($token, E_ERROR, 'message-2'); + $context = new HTMLPurifier_Context(); + $context->register('Locale', $language); + + $collector = new HTMLPurifier_ErrorCollector($context); + $collector->send(E_ERROR, 'message-1'); + $collector->send(E_ERROR, 'message-2'); $result = array( - 0 => array(false, E_ERROR, 'Message 1'), - 1 => array(false, E_ERROR, 'Message 2') + 0 => array(null, E_ERROR, 'Message 1'), + 1 => array(null, E_ERROR, 'Message 2') ); $this->assertIdentical($collector->getRaw(), $result);