From 020281d932c566476222e6c825ada3affff239a6 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sat, 29 Aug 2009 10:45:47 -0700 Subject: Adding SafeString which is going to replace p::clean() and p::purify(). Refactoring of Xss_Security_Test. t() and t2() return a SafeString instance. TODO: - Update all code to use SafeString where appropriate. - Update golden fole of Xss_Security_Test - Stop reporting CLEAN vars in Xss_Security_Test --- modules/gallery/tests/SafeString_Test.php | 111 ++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 modules/gallery/tests/SafeString_Test.php (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php new file mode 100644 index 00000000..cdae3e99 --- /dev/null +++ b/modules/gallery/tests/SafeString_Test.php @@ -0,0 +1,111 @@ +world

"); + $this->assert_true($safe_string instanceof SafeString); + $this->assert_equal("hello

world

", + $safe_string->unescaped()); + } + + public function toString_escapes_for_html_test() { + $safe_string = new SafeString("hello

world

"); + $this->assert_equal("hello <p>world</p>", + $safe_string); + } + + public function toString_for_safe_string_test() { + $safe_string = new SafeString("hello

world

"); + $safe_string->mark_html_safe(); + $this->assert_equal("hello

world

", + $safe_string); + } + + public function for_html_test() { + $safe_string = new SafeString("hello

world

"); + $this->assert_equal("hello <p>world</p>", + $safe_string->for_html()); + } + + public function safestring_of_safestring_test() { + $safe_string = new SafeString("hello

world

"); + $safe_string_2 = new SafeString($safe_string); + $this->assert_true($safe_string_2 instanceof SafeString); + $raw_string = $safe_string_2->unescaped(); + $this->assert_false(is_object($raw_string)); + $this->assert_equal("hello

world

", $raw_string); + $this->assert_equal("hello <p>world</p>", $safe_string_2); + } + + public function for_js_test() { + $safe_string = new SafeString('"Foo\'s bar"'); + $js_string = $safe_string->for_js(); + $this->assert_equal('\\"Foo<\\/em>\\\'s bar\\"', + $js_string); + } + + public function string_safestring_equality_test() { + $safe_string = new SafeString("hello

world

"); + $this->assert_equal("hello

world

", + $safe_string->unescaped()); + $escaped_string = "hello <p>world</p>"; + $this->assert_equal($escaped_string, $safe_string); + + $this->assert_true($escaped_string == $safe_string); + $this->assert_false($escaped_string === $safe_string); + $this->assert_false("meow" == $safe_string); + } + + public function of_test() { + $safe_string = SafeString::of("hello

world

"); + $this->assert_equal("hello

world

", $safe_string->unescaped()); + } + + public function of_safe_html_test() { + $safe_string = SafeString::of("hello

world

")->mark_html_safe(); + $this->assert_equal("hello

world

", $safe_string->for_html()); + } + + public function of_fluid_api_test() { + $escaped_string = SafeString::of("Foo's bar")->for_js(); + $this->assert_equal("Foo\\'s bar", $escaped_string); + } + + public function safestring_of_safestring_preserves_safe_status_test() { + $safe_string = SafeString::of("hello's

world

")->mark_html_safe(); + $safe_string_2 = new SafeString($safe_string); + $this->assert_equal("hello's

world

", $safe_string_2); + $this->assert_equal("hello\\'s

world<\\/p>", $safe_string_2->for_js()); + } + + public function safestring_of_safestring_preserves_html_safe_status_test() { + $safe_string = SafeString::of("hello's

world

") + ->mark_html_safe(); + $safe_string_2 = new SafeString($safe_string); + $this->assert_equal("hello's

world

", $safe_string_2); + $this->assert_equal("hello\\'s

world<\\/p>", $safe_string_2->for_js()); + } + + public function safestring_of_safestring_safe_status_override_test() { + $safe_string = new SafeString("hello

world

"); + $safe_string_2 = SafeString::of($safe_string)->mark_html_safe(); + $this->assert_equal("hello

world

", $safe_string_2); + } +} -- cgit v1.2.3 From 7adb9ea2e3a42e1c5472024a1699912ae26eacb3 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sat, 29 Aug 2009 11:48:55 -0700 Subject: Adding SafeString::for_html_attr() --- modules/gallery/libraries/SafeString.php | 19 +++++++++++++++++++ modules/gallery/tests/SafeString_Test.php | 21 ++++++++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php index 53bcb27a..709ab5f6 100644 --- a/modules/gallery/libraries/SafeString.php +++ b/modules/gallery/libraries/SafeString.php @@ -89,6 +89,25 @@ class SafeString_Core { return self::_escape_for_js($this->_raw_string); } + /** + * Safe for use in HTML element attributes. + * + * Assumes that the HTML element attribute is already + * delimited by single or double quotes + * + * Example:
+   *     ;
+   *   
+   * 
+ * @return the string escaped for use in HTML attributes. + */ + function for_html_attr() { + $string = (string) $this->for_html(); + return strtr($string, + array("'"=>"'", + '"'=>'"')); + } + /** * Safe for use HTML (purified HTML) * diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index cdae3e99..73d82c34 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -18,13 +18,6 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class SafeString_Test extends Unit_Test_Case { - public function p_clean_returns_safestring_instance_test() { - $safe_string = p::clean("hello

world

"); - $this->assert_true($safe_string instanceof SafeString); - $this->assert_equal("hello

world

", - $safe_string->unescaped()); - } - public function toString_escapes_for_html_test() { $safe_string = new SafeString("hello

world

"); $this->assert_equal("hello <p>world</p>", @@ -61,6 +54,20 @@ class SafeString_Test extends Unit_Test_Case { $js_string); } + public function for_html_attr_test() { + $safe_string = new SafeString('"Foo\'s bar"'); + $attr_string = $safe_string->for_html_attr(); + $this->assert_equal('"<em>Foo</em>'s bar"', + $attr_string); + } + + public function for_html_attr_with_safe_html_test() { + $safe_string = SafeString::of('"Foo\'s bar"')->mark_html_safe(); + $attr_string = $safe_string->for_html_attr(); + $this->assert_equal('"Foo's bar"', + $attr_string); + } + public function string_safestring_equality_test() { $safe_string = new SafeString("hello

world

"); $this->assert_equal("hello

world

", -- cgit v1.2.3 From a10063ff68cf5988297dcad889384ab2080c3850 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sat, 29 Aug 2009 12:34:09 -0700 Subject: Add more factory methods for convenience: SafeString::purify() and SafeString::of_safe_html(). Removing SafeString::mark_html_safe() since it's no longer needed. --- modules/gallery/helpers/MY_url.php | 10 +++++----- modules/gallery/libraries/I18n.php | 2 +- modules/gallery/libraries/SafeString.php | 27 +++++++++++++++++++++------ modules/gallery/tests/SafeString_Test.php | 19 +++++++++++-------- modules/gallery/tests/Xss_Security_Test.php | 7 +++++-- 5 files changed, 43 insertions(+), 22 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/helpers/MY_url.php b/modules/gallery/helpers/MY_url.php index b4b7f352..6092a9d8 100644 --- a/modules/gallery/helpers/MY_url.php +++ b/modules/gallery/helpers/MY_url.php @@ -31,7 +31,7 @@ class url extends url_Core { $uri = model_cache::get("item", $parts[1])->relative_path(); } $url = parent::site($uri . $query, $protocol); - return SafeString::of($url)->mark_html_safe(); + return SafeString::of_safe_html($url); } static function parse_url() { @@ -103,22 +103,22 @@ class url extends url_Core { public static function base($index=false, $protocol=false) { $url = parent::base($index, $protocol); - return SafeString::of($url)->mark_html_safe(); + return SafeString::of_safe_html($url); } public static function current($qs=false) { $url = parent::current($qs); - return SafeString::of($url)->mark_html_safe(); + return SafeString::of_safe_html($url); } public static function file($file, $index=false) { $url = parent::file($file, $index); - return SafeString::of($url)->mark_html_safe(); + return SafeString::of_safe_html($url); } public static function merge(array $arguments) { $url = parent::merge($arguments); - return SafeString::of($url)->mark_html_safe(); + return SafeString::of_safe_html($url); } } diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php index 8dc42e04..a53d5ae9 100644 --- a/modules/gallery/libraries/I18n.php +++ b/modules/gallery/libraries/I18n.php @@ -116,7 +116,7 @@ class I18n_Core { $entry = $this->interpolate($locale, $entry, $values); - return SafeString::of($entry)->mark_html_safe(); + return SafeString::of_safe_html($entry); } private function lookup($locale, $message) { diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php index 709ab5f6..9a269ed4 100644 --- a/modules/gallery/libraries/SafeString.php +++ b/modules/gallery/libraries/SafeString.php @@ -24,6 +24,7 @@ class SafeString_Core { private $_raw_string; protected $_is_safe_html = false; + protected $_is_purified_html = false; private static $_purifier = null; @@ -44,11 +45,25 @@ class SafeString_Core { } /** - * Marks this string as safe to be used in HTML without any escaping. + * Factory method returning a new SafeString instance after HTML purifying + * the given string. */ - function mark_html_safe() { - $this->_is_safe_html = true; - return $this; + static function purify($string) { + if ($string instanceof SafeString) { + $string = $string->unescaped(); + } + $safe_string = self::of_safe_html(self::_purify_for_html($string)); + $safe_string->_is_purified_html = true; + return $safe_string; + } + + /** + * Factory method returning a new SafeString instance which won't HTML escape. + */ + static function of_safe_html($string) { + $safe_string = new SafeString($string); + $safe_string->_is_safe_html = true; + return $safe_string; } /** @@ -117,10 +132,10 @@ class SafeString_Core { * @return the string escaped for use in HTML. */ function purified_html() { - if ($this->_is_safe_html) { + if ($this->_is_purified_html) { return $this; } else { - return SafeString::of(self::_purify_for_html($this->_raw_string), true); + return self::purify($this); } } diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index 73d82c34..0fc7f6f3 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -25,8 +25,7 @@ class SafeString_Test extends Unit_Test_Case { } public function toString_for_safe_string_test() { - $safe_string = new SafeString("hello

world

"); - $safe_string->mark_html_safe(); + $safe_string = SafeString::of_safe_html("hello

world

"); $this->assert_equal("hello

world

", $safe_string); } @@ -62,7 +61,7 @@ class SafeString_Test extends Unit_Test_Case { } public function for_html_attr_with_safe_html_test() { - $safe_string = SafeString::of('"Foo\'s bar"')->mark_html_safe(); + $safe_string = SafeString::of_safe_html('"Foo\'s bar"'); $attr_string = $safe_string->for_html_attr(); $this->assert_equal('"Foo's bar"', $attr_string); @@ -86,25 +85,29 @@ class SafeString_Test extends Unit_Test_Case { } public function of_safe_html_test() { - $safe_string = SafeString::of("hello

world

")->mark_html_safe(); + $safe_string = SafeString::of_safe_html("hello

world

"); $this->assert_equal("hello

world

", $safe_string->for_html()); } + public function purify_test() { + $safe_string = SafeString::purify("hello

world

"); + $this->assert_equal("hello

world

", $safe_string); + } + public function of_fluid_api_test() { $escaped_string = SafeString::of("Foo's bar")->for_js(); $this->assert_equal("Foo\\'s bar", $escaped_string); } public function safestring_of_safestring_preserves_safe_status_test() { - $safe_string = SafeString::of("hello's

world

")->mark_html_safe(); + $safe_string = SafeString::of_safe_html("hello's

world

"); $safe_string_2 = new SafeString($safe_string); $this->assert_equal("hello's

world

", $safe_string_2); $this->assert_equal("hello\\'s

world<\\/p>", $safe_string_2->for_js()); } public function safestring_of_safestring_preserves_html_safe_status_test() { - $safe_string = SafeString::of("hello's

world

") - ->mark_html_safe(); + $safe_string = SafeString::of_safe_html("hello's

world

"); $safe_string_2 = new SafeString($safe_string); $this->assert_equal("hello's

world

", $safe_string_2); $this->assert_equal("hello\\'s

world<\\/p>", $safe_string_2->for_js()); @@ -112,7 +115,7 @@ class SafeString_Test extends Unit_Test_Case { public function safestring_of_safestring_safe_status_override_test() { $safe_string = new SafeString("hello

world

"); - $safe_string_2 = SafeString::of($safe_string)->mark_html_safe(); + $safe_string_2 = SafeString::of_safe_html($safe_string); $this->assert_equal("hello

world

", $safe_string_2); } } diff --git a/modules/gallery/tests/Xss_Security_Test.php b/modules/gallery/tests/Xss_Security_Test.php index e0e5bb86..fd596c69 100644 --- a/modules/gallery/tests/Xss_Security_Test.php +++ b/modules/gallery/tests/Xss_Security_Test.php @@ -110,10 +110,13 @@ class Xss_Security_Test extends Unit_Test_Case { } else if ($token[1] == "SafeString") { // Looking for SafeString::of(... if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && - self::_token_matches(array(T_STRING, "of"), $tokens, $token_number + 2) && + self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && + in_array($tokens[$token_number + 2][1], array("of", "of_safe_html", "purify")) && self::_token_matches("(", $tokens, $token_number + 3)) { $frame->is_safestring(true); - $frame->expr_append("::of("); + + $method = $tokens[$token_number + 2][1]; + $frame->expr_append("::$method("); $token_number += 3; $token = $tokens[$token_number]; -- cgit v1.2.3 From beb711d6a0fedac0d4ca3b9bae162a6ce9d6cdeb Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 30 Aug 2009 15:21:02 -0700 Subject: Rename clean_js to js_string and have it return a complete JS string (with delimiters) instead of just the string contents. Benefits: Using json_encode(), which is very robust. And as a user, it's clearer how to use this API compared to what it was before. --- modules/gallery/helpers/MY_html.php | 4 ++-- modules/gallery/libraries/SafeString.php | 14 +++----------- modules/gallery/tests/Html_Helper_Test.php | 6 +++--- modules/gallery/tests/SafeString_Test.php | 8 ++++---- modules/gallery/tests/Xss_Security_Test.php | 4 ++-- 5 files changed, 14 insertions(+), 22 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/helpers/MY_html.php b/modules/gallery/helpers/MY_html.php index 75114898..4522d01c 100644 --- a/modules/gallery/helpers/MY_html.php +++ b/modules/gallery/helpers/MY_html.php @@ -65,11 +65,11 @@ class html extends html_Core { * * Example:
    *   
    * 
*/ - static function clean_js($string) { + static function js_string($string) { return SafeString::of($string)->for_js(); } diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php index 9614a213..0767a665 100644 --- a/modules/gallery/libraries/SafeString.php +++ b/modules/gallery/libraries/SafeString.php @@ -92,17 +92,17 @@ class SafeString_Core { } /** - * Safe for use in JavaScript. + * Safe for use as JavaScript string. * * Example:
    *   
    * 
* @return the string escaped for use in JavaScript. */ function for_js() { - return self::_escape_for_js($this->_raw_string); + return json_encode((string) $this->_raw_string); } /** @@ -152,14 +152,6 @@ class SafeString_Core { return html::specialchars($dirty_html); } - // Escapes special chars (quotes, backslash, etc.) with a backslash sequence. - private static function _escape_for_js($string) { - // From Smarty plugins/modifier.escape.php - // Might want to be stricter here. - return strtr($string, - array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n',''<\/')); - } - // Purifies the string, removing any potentially malicious or unsafe HTML / JavaScript. private static function _purify_for_html($dirty_html) { if (empty(self::$_purifier)) { diff --git a/modules/gallery/tests/Html_Helper_Test.php b/modules/gallery/tests/Html_Helper_Test.php index a9903256..f5ce7fa4 100644 --- a/modules/gallery/tests/Html_Helper_Test.php +++ b/modules/gallery/tests/Html_Helper_Test.php @@ -40,9 +40,9 @@ class Html_Helper_Test extends Unit_Test_Case { $safe_string_2); } - public function clean_js_test() { - $string = html::clean_js("hello's

world

"); - $this->assert_equal("hello\\'s

world<\\/p>", + public function js_string_test() { + $string = html::js_string("hello's

world

"); + $this->assert_equal('"hello\'s

world<\\/p>"', $string); } diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index 0fc7f6f3..ede55240 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -49,7 +49,7 @@ class SafeString_Test extends Unit_Test_Case { public function for_js_test() { $safe_string = new SafeString('"Foo\'s bar"'); $js_string = $safe_string->for_js(); - $this->assert_equal('\\"Foo<\\/em>\\\'s bar\\"', + $this->assert_equal('"\\"Foo<\\/em>\'s bar\\""', $js_string); } @@ -96,21 +96,21 @@ class SafeString_Test extends Unit_Test_Case { public function of_fluid_api_test() { $escaped_string = SafeString::of("Foo's bar")->for_js(); - $this->assert_equal("Foo\\'s bar", $escaped_string); + $this->assert_equal('"Foo\'s bar"', $escaped_string); } public function safestring_of_safestring_preserves_safe_status_test() { $safe_string = SafeString::of_safe_html("hello's

world

"); $safe_string_2 = new SafeString($safe_string); $this->assert_equal("hello's

world

", $safe_string_2); - $this->assert_equal("hello\\'s

world<\\/p>", $safe_string_2->for_js()); + $this->assert_equal('"hello\'s

world<\\/p>"', $safe_string_2->for_js()); } public function safestring_of_safestring_preserves_html_safe_status_test() { $safe_string = SafeString::of_safe_html("hello's

world

"); $safe_string_2 = new SafeString($safe_string); $this->assert_equal("hello's

world

", $safe_string_2); - $this->assert_equal("hello\\'s

world<\\/p>", $safe_string_2->for_js()); + $this->assert_equal('"hello\'s

world<\\/p>"', $safe_string_2->for_js()); } public function safestring_of_safestring_safe_status_override_test() { diff --git a/modules/gallery/tests/Xss_Security_Test.php b/modules/gallery/tests/Xss_Security_Test.php index b385580d..3a22afc1 100644 --- a/modules/gallery/tests/Xss_Security_Test.php +++ b/modules/gallery/tests/Xss_Security_Test.php @@ -188,7 +188,7 @@ class Xss_Security_Test extends Unit_Test_Case { if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && in_array($tokens[$token_number + 2][1], - array("clean", "purify", "clean_js", "clean_attribute")) && + array("clean", "purify", "js_string", "clean_attribute")) && self::_token_matches("(", $tokens, $token_number + 3)) { // Not checking for mark_safe(). We want such calls to be marked dirty (thus reviewed). @@ -198,7 +198,7 @@ class Xss_Security_Test extends Unit_Test_Case { $token_number += 3; $token = $tokens[$token_number]; - if ("clean_js" == $method) { + if ("js_string" == $method) { $frame->is_safe_js(true); } else { $frame->is_safe_html(true); -- cgit v1.2.3 From df38a890a64dd33eafe3aed51ce8fde732cf8b8b Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Sun, 30 Aug 2009 18:07:13 -0700 Subject: Tabs to spaces cleanup --- modules/gallery/controllers/admin_languages.php | 32 +- modules/gallery/controllers/l10n_client.php | 8 +- modules/gallery/helpers/gallery.php | 6 +- modules/gallery/libraries/SafeString.php | 4 +- modules/gallery/tests/Html_Helper_Test.php | 10 +- modules/gallery/tests/SafeString_Test.php | 14 +- modules/gallery/tests/Xss_Security_Test.php | 380 ++++++++++++------------ modules/server_add/helpers/server_add_event.php | 2 +- 8 files changed, 228 insertions(+), 228 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php index b1bc4cff..d85c47f9 100644 --- a/modules/gallery/controllers/admin_languages.php +++ b/modules/gallery/controllers/admin_languages.php @@ -21,10 +21,10 @@ class Admin_Languages_Controller extends Admin_Controller { public function index($share_translations_form=null) { $v = new Admin_View("admin.html"); $v->content = new View("admin_languages.html"); - $v->content->available_locales = locales::available(); + $v->content->available_locales = locales::available(); $v->content->installed_locales = locales::installed(); $v->content->default_locale = module::get_var("gallery", "default_locale"); - + if (empty($share_translations_form)) { $share_translations_form = $this->_share_translations_form(); } @@ -35,21 +35,21 @@ class Admin_Languages_Controller extends Admin_Controller { public function save() { access::verify_csrf(); - - locales::update_installed($this->input->post("installed_locales")); - - $installed_locales = array_keys(locales::installed()); + + locales::update_installed($this->input->post("installed_locales")); + + $installed_locales = array_keys(locales::installed()); $new_default_locale = $this->input->post("default_locale"); - if (!in_array($new_default_locale, $installed_locales)) { - if (!empty($installed_locales)) { - $new_default_locale = $installed_locales[0]; - } else { - $new_default_locale = "en_US"; - } - } - module::set_var("gallery", "default_locale", $new_default_locale); - - print json_encode(array("result" => "success")); + if (!in_array($new_default_locale, $installed_locales)) { + if (!empty($installed_locales)) { + $new_default_locale = $installed_locales[0]; + } else { + $new_default_locale = "en_US"; + } + } + module::set_var("gallery", "default_locale", $new_default_locale); + + print json_encode(array("result" => "success")); } public function share() { diff --git a/modules/gallery/controllers/l10n_client.php b/modules/gallery/controllers/l10n_client.php index 0775791e..16d39024 100644 --- a/modules/gallery/controllers/l10n_client.php +++ b/modules/gallery/controllers/l10n_client.php @@ -90,13 +90,13 @@ class L10n_Client_Controller extends Controller { } $session = Session::instance(); - $l10n_mode = $session->get("l10n_mode", false); + $l10n_mode = $session->get("l10n_mode", false); $session->set("l10n_mode", !$l10n_mode); $redirect_url = "admin/languages"; - if (!$l10n_mode) { - $redirect_url .= "#l10n-client"; - } + if (!$l10n_mode) { + $redirect_url .= "#l10n-client"; + } url::redirect($redirect_url); } diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php index 122227fc..035ed1da 100644 --- a/modules/gallery/helpers/gallery.php +++ b/modules/gallery/helpers/gallery.php @@ -92,7 +92,7 @@ class gallery_Core { $can_add = $item && access::can("add", $item); if ($can_add) { - $menu->append($add_menu = Menu::factory("submenu") + $menu->append($add_menu = Menu::factory("submenu") ->id("add_menu") ->label(t("Add"))); $add_menu->append(Menu::factory("dialog") @@ -100,11 +100,11 @@ class gallery_Core { ->label(t("Add photos")) ->url(url::site("simple_uploader/app/$item->id"))); if ($item->is_album()) { - $add_menu->append(Menu::factory("dialog") + $add_menu->append(Menu::factory("dialog") ->id("add_album_item") ->label(t("Add an album")) ->url(url::site("form/add/albums/$item->id?type=album"))); - } + } } $menu->append($options_menu = Menu::factory("submenu") diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php index 0767a665..cc542e01 100644 --- a/modules/gallery/libraries/SafeString.php +++ b/modules/gallery/libraries/SafeString.php @@ -120,8 +120,8 @@ class SafeString_Core { function for_html_attr() { $string = (string) $this->for_html(); return strtr($string, - array("'"=>"'", - '"'=>'"')); + array("'"=>"'", + '"'=>'"')); } /** diff --git a/modules/gallery/tests/Html_Helper_Test.php b/modules/gallery/tests/Html_Helper_Test.php index f5ce7fa4..3623705e 100644 --- a/modules/gallery/tests/Html_Helper_Test.php +++ b/modules/gallery/tests/Html_Helper_Test.php @@ -21,14 +21,14 @@ class Html_Helper_Test extends Unit_Test_Case { public function clean_test() { $safe_string = html::clean("hello

world

"); $this->assert_equal("hello <p >world</p>", - $safe_string); + $safe_string); $this->assert_true($safe_string instanceof SafeString); } public function purify_test() { $safe_string = html::purify("hello

world

"); $this->assert_equal("hello

world

", - $safe_string); + $safe_string); $this->assert_true($safe_string instanceof SafeString); } @@ -37,19 +37,19 @@ class Html_Helper_Test extends Unit_Test_Case { $this->assert_true($safe_string instanceof SafeString); $safe_string_2 = html::clean($safe_string); $this->assert_equal("hello

world

", - $safe_string_2); + $safe_string_2); } public function js_string_test() { $string = html::js_string("hello's

world

"); $this->assert_equal('"hello\'s

world<\\/p>"', - $string); + $string); } public function clean_attribute_test() { $safe_string = SafeString::of_safe_html("hello's

world

"); $safe_string = html::clean_attribute($safe_string); $this->assert_equal("hello's

world

", - $safe_string); + $safe_string); } } \ No newline at end of file diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index ede55240..0895b7dd 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -21,19 +21,19 @@ class SafeString_Test extends Unit_Test_Case { public function toString_escapes_for_html_test() { $safe_string = new SafeString("hello

world

"); $this->assert_equal("hello <p>world</p>", - $safe_string); + $safe_string); } public function toString_for_safe_string_test() { $safe_string = SafeString::of_safe_html("hello

world

"); $this->assert_equal("hello

world

", - $safe_string); + $safe_string); } public function for_html_test() { $safe_string = new SafeString("hello

world

"); $this->assert_equal("hello <p>world</p>", - $safe_string->for_html()); + $safe_string->for_html()); } public function safestring_of_safestring_test() { @@ -50,27 +50,27 @@ class SafeString_Test extends Unit_Test_Case { $safe_string = new SafeString('"Foo\'s bar"'); $js_string = $safe_string->for_js(); $this->assert_equal('"\\"Foo<\\/em>\'s bar\\""', - $js_string); + $js_string); } public function for_html_attr_test() { $safe_string = new SafeString('"Foo\'s bar"'); $attr_string = $safe_string->for_html_attr(); $this->assert_equal('"<em>Foo</em>'s bar"', - $attr_string); + $attr_string); } public function for_html_attr_with_safe_html_test() { $safe_string = SafeString::of_safe_html('"Foo\'s bar"'); $attr_string = $safe_string->for_html_attr(); $this->assert_equal('"Foo's bar"', - $attr_string); + $attr_string); } public function string_safestring_equality_test() { $safe_string = new SafeString("hello

world

"); $this->assert_equal("hello

world

", - $safe_string->unescaped()); + $safe_string->unescaped()); $escaped_string = "hello <p>world</p>"; $this->assert_equal($escaped_string, $safe_string); diff --git a/modules/gallery/tests/Xss_Security_Test.php b/modules/gallery/tests/Xss_Security_Test.php index 3a22afc1..6c141c52 100644 --- a/modules/gallery/tests/Xss_Security_Test.php +++ b/modules/gallery/tests/Xss_Security_Test.php @@ -24,9 +24,9 @@ class Xss_Security_Test extends Unit_Test_Case { // List of all tokens without whitespace, simplifying parsing. $tokens = array(); foreach (token_get_all(file_get_contents($view)) as $token) { - if (!is_array($token) || ($token[0] != T_WHITESPACE)) { - $tokens[] = $token; - } + if (!is_array($token) || ($token[0] != T_WHITESPACE)) { + $tokens[] = $token; + } } $frame = null; @@ -34,199 +34,199 @@ class Xss_Security_Test extends Unit_Test_Case { $in_script_block = false; for ($token_number = 0; $token_number < count($tokens); $token_number++) { - $token = $tokens[$token_number]; - - // Are we in a block? - if (is_array($token) && $token[0] == T_INLINE_HTML) { - $inline_html = $token[1]; - // T_INLINE_HTML blocks can be split. Need to handle the case - // where one token has "expr_append($inline_html); - } - - // Note: This approach won't catch }i', $inline_html, $matches, PREG_OFFSET_CAPTURE)) { - $last_match = array_pop($matches[0]); - if (is_array($last_match)) { - $closing_script_pos = $last_match[1]; - } else { - $closing_script_pos = $last_match; - } - } - if (preg_match('{]*>}i', $inline_html, $matches, PREG_OFFSET_CAPTURE)) { - $last_match = array_pop($matches[0]); - if (is_array($last_match)) { - $opening_script_pos = $last_match[1]; - } else { - $opening_script_pos = $last_match; - } - } - if ($opening_script_pos != $closing_script_pos) { - $in_script_block = $opening_script_pos > $closing_script_pos; - } - } - - // Look and report each instance of < ? = ... ? > - if (!is_array($token)) { - // A single char token, e.g: ; ( ) - if ($frame) { - $frame->expr_append($token); - } - } else if ($token[0] == T_OPEN_TAG_WITH_ECHO) { - // No need for a stack here - assume < ? = cannot be nested. - $frame = self::_create_frame($token, $in_script_block); + $token = $tokens[$token_number]; + + // Are we in a block? + if (is_array($token) && $token[0] == T_INLINE_HTML) { + $inline_html = $token[1]; + // T_INLINE_HTML blocks can be split. Need to handle the case + // where one token has "expr_append($inline_html); + } + + // Note: This approach won't catch }i', $inline_html, $matches, PREG_OFFSET_CAPTURE)) { + $last_match = array_pop($matches[0]); + if (is_array($last_match)) { + $closing_script_pos = $last_match[1]; + } else { + $closing_script_pos = $last_match; + } + } + if (preg_match('{]*>}i', $inline_html, $matches, PREG_OFFSET_CAPTURE)) { + $last_match = array_pop($matches[0]); + if (is_array($last_match)) { + $opening_script_pos = $last_match[1]; + } else { + $opening_script_pos = $last_match; + } + } + if ($opening_script_pos != $closing_script_pos) { + $in_script_block = $opening_script_pos > $closing_script_pos; + } + } + + // Look and report each instance of < ? = ... ? > + if (!is_array($token)) { + // A single char token, e.g: ; ( ) + if ($frame) { + $frame->expr_append($token); + } + } else if ($token[0] == T_OPEN_TAG_WITH_ECHO) { + // No need for a stack here - assume < ? = cannot be nested. + $frame = self::_create_frame($token, $in_script_block); } else if ($frame && $token[0] == T_CLOSE_TAG) { - // Store the < ? = ... ? > block that just ended here. - $found[$view][] = $frame; - $frame = null; + // Store the < ? = ... ? > block that just ended here. + $found[$view][] = $frame; + $frame = null; } else if ($frame && $token[0] == T_VARIABLE) { - $frame->expr_append($token[1]); + $frame->expr_append($token[1]); if ($token[1] == '$theme') { - if (self::_token_matches(array(T_OBJECT_OPERATOR, "->"), $tokens, $token_number + 1) && - self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && - in_array($tokens[$token_number + 2][1], - array("thumb_proportion", "site_menu", "album_menu", "tag_menu", "photo_menu", + if (self::_token_matches(array(T_OBJECT_OPERATOR, "->"), $tokens, $token_number + 1) && + self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && + in_array($tokens[$token_number + 2][1], + array("thumb_proportion", "site_menu", "album_menu", "tag_menu", "photo_menu", "context_menu", "pager", "site_status", "messages", "album_blocks", "album_bottom", "album_top", "body_attributes", "credits", "dynamic_bottom", "dynamic_top", "footer", "head", "header_bottom", "header_top", "page_bottom", "page_top", "photo_blocks", "photo_bottom", "photo_top", "resize_bottom", "resize_top", "sidebar_blocks", "sidebar_bottom", "sidebar_top", "thumb_bottom", "thumb_info", "thumb_top")) && - self::_token_matches("(", $tokens, $token_number + 3)) { + self::_token_matches("(", $tokens, $token_number + 3)) { - $method = $tokens[$token_number + 2][1]; - $frame->expr_append("->$method("); + $method = $tokens[$token_number + 2][1]; + $frame->expr_append("->$method("); - $token_number += 3; - $token = $tokens[$token_number]; + $token_number += 3; + $token = $tokens[$token_number]; $frame->is_safe_html(true); - } else if (self::_token_matches(array(T_OBJECT_OPERATOR, "->"), $tokens, $token_number + 1) && - self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && - in_array($tokens[$token_number + 2][1], - array("css", "script", "url")) && - self::_token_matches("(", $tokens, $token_number + 3) && - // Only allow constant strings here - self::_token_matches(array(T_CONSTANT_ENCAPSED_STRING), $tokens, $token_number + 4)) { + } else if (self::_token_matches(array(T_OBJECT_OPERATOR, "->"), $tokens, $token_number + 1) && + self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && + in_array($tokens[$token_number + 2][1], + array("css", "script", "url")) && + self::_token_matches("(", $tokens, $token_number + 3) && + // Only allow constant strings here + self::_token_matches(array(T_CONSTANT_ENCAPSED_STRING), $tokens, $token_number + 4)) { - $method = $tokens[$token_number + 2][1]; - $frame->expr_append("->$method("); + $method = $tokens[$token_number + 2][1]; + $frame->expr_append("->$method("); - $token_number += 4; - $token = $tokens[$token_number]; + $token_number += 4; + $token = $tokens[$token_number]; $frame->is_safe_html(true); - } + } } - } else if ($frame && $token[0] == T_STRING) { - $frame->expr_append($token[1]); - // t() and t2() are special in that they're guaranteed to return a SafeString(). - if (in_array($token[1], array("t", "t2"))) { - if (self::_token_matches("(", $tokens, $token_number + 1)) { - $frame->is_safe_html(true); - $frame->expr_append("("); - - $token_number++; - $token = $tokens[$token_number]; - } - } else if ($token[1] == "SafeString") { - // Looking for SafeString::of(... - if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && - self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && - in_array($tokens[$token_number + 2][1], array("of", "purify")) && - self::_token_matches("(", $tokens, $token_number + 3)) { + } else if ($frame && $token[0] == T_STRING) { + $frame->expr_append($token[1]); + // t() and t2() are special in that they're guaranteed to return a SafeString(). + if (in_array($token[1], array("t", "t2"))) { + if (self::_token_matches("(", $tokens, $token_number + 1)) { + $frame->is_safe_html(true); + $frame->expr_append("("); + + $token_number++; + $token = $tokens[$token_number]; + } + } else if ($token[1] == "SafeString") { + // Looking for SafeString::of(... + if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && + self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && + in_array($tokens[$token_number + 2][1], array("of", "purify")) && + self::_token_matches("(", $tokens, $token_number + 3)) { // Not checking for of_safe_html(). We want such calls to be marked dirty (thus reviewed). - $frame->is_safe_html(true); - - $method = $tokens[$token_number + 2][1]; - $frame->expr_append("::$method("); - - $token_number += 3; - $token = $tokens[$token_number]; - } - } else if ($token[1] == "json_encode") { - if (self::_token_matches("(", $tokens, $token_number + 1)) { - $frame->is_safe_js(true); - $frame->expr_append("("); - - $token_number++; - $token = $tokens[$token_number]; - } - } else if ($token[1] == "url") { - // url methods return safe HTML - if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && - self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && - in_array($tokens[$token_number + 2][1], - array("site", "current", "base", "file", "abs_site", "abs_current", - "abs_file", "merge")) && - self::_token_matches("(", $tokens, $token_number + 3)) { - $frame->is_safe_html(true); - - $method = $tokens[$token_number + 2][1]; - $frame->expr_append("::$method("); - - $token_number += 3; - $token = $tokens[$token_number]; - } - } else if ($token[1] == "html") { - if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && - self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && - in_array($tokens[$token_number + 2][1], - array("clean", "purify", "js_string", "clean_attribute")) && - self::_token_matches("(", $tokens, $token_number + 3)) { + $frame->is_safe_html(true); + + $method = $tokens[$token_number + 2][1]; + $frame->expr_append("::$method("); + + $token_number += 3; + $token = $tokens[$token_number]; + } + } else if ($token[1] == "json_encode") { + if (self::_token_matches("(", $tokens, $token_number + 1)) { + $frame->is_safe_js(true); + $frame->expr_append("("); + + $token_number++; + $token = $tokens[$token_number]; + } + } else if ($token[1] == "url") { + // url methods return safe HTML + if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && + self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && + in_array($tokens[$token_number + 2][1], + array("site", "current", "base", "file", "abs_site", "abs_current", + "abs_file", "merge")) && + self::_token_matches("(", $tokens, $token_number + 3)) { + $frame->is_safe_html(true); + + $method = $tokens[$token_number + 2][1]; + $frame->expr_append("::$method("); + + $token_number += 3; + $token = $tokens[$token_number]; + } + } else if ($token[1] == "html") { + if (self::_token_matches(array(T_DOUBLE_COLON, "::"), $tokens, $token_number + 1) && + self::_token_matches(array(T_STRING), $tokens, $token_number + 2) && + in_array($tokens[$token_number + 2][1], + array("clean", "purify", "js_string", "clean_attribute")) && + self::_token_matches("(", $tokens, $token_number + 3)) { // Not checking for mark_safe(). We want such calls to be marked dirty (thus reviewed). - $method = $tokens[$token_number + 2][1]; - $frame->expr_append("::$method("); + $method = $tokens[$token_number + 2][1]; + $frame->expr_append("::$method("); - $token_number += 3; - $token = $tokens[$token_number]; + $token_number += 3; + $token = $tokens[$token_number]; if ("js_string" == $method) { $frame->is_safe_js(true); } else { $frame->is_safe_html(true); } - } - } - } else if ($frame && $token[0] == T_OBJECT_OPERATOR) { - $frame->expr_append($token[1]); - - if (self::_token_matches(array(T_STRING), $tokens, $token_number + 1) && - in_array($tokens[$token_number + 1][1], - array("for_js", "for_html", "purified_html", "for_html_attr")) && - self::_token_matches("(", $tokens, $token_number + 2)) { - $method = $tokens[$token_number + 1][1]; - $frame->expr_append("$method("); - - $token_number += 2; - $token = $tokens[$token_number]; - - if ("for_js" == $method) { - $frame->is_safe_js(true); - } else { - $frame->is_safe_html(true); - } - } + } + } + } else if ($frame && $token[0] == T_OBJECT_OPERATOR) { + $frame->expr_append($token[1]); + + if (self::_token_matches(array(T_STRING), $tokens, $token_number + 1) && + in_array($tokens[$token_number + 1][1], + array("for_js", "for_html", "purified_html", "for_html_attr")) && + self::_token_matches("(", $tokens, $token_number + 2)) { + $method = $tokens[$token_number + 1][1]; + $frame->expr_append("$method("); + + $token_number += 2; + $token = $tokens[$token_number]; + + if ("for_js" == $method) { + $frame->is_safe_js(true); + } else { + $frame->is_safe_html(true); + } + } } else if ($frame) { - $frame->expr_append($token[1]); - } + $frame->expr_append($token[1]); + } } } @@ -252,26 +252,26 @@ class Xss_Security_Test extends Unit_Test_Case { ksort($found); foreach ($found as $view => $frames) { foreach ($frames as $frame) { - $state = "DIRTY"; - if ($frame->in_script_block()) { - $state = "DIRTY_JS"; - if ($frame->is_safe_js()) { - $state = "CLEAN"; - } - } else { - if ($frame->is_safe_html()) { - $state = "CLEAN"; - } - } - - if ("CLEAN" == $state) { - // Don't print CLEAN instances - No need to update the golden - // file when adding / moving clean instances. - continue; - } - - fprintf($fd, "%-60s %-3s %-8s %s\n", - $view, $frame->line(), $state, $frame->expr()); + $state = "DIRTY"; + if ($frame->in_script_block()) { + $state = "DIRTY_JS"; + if ($frame->is_safe_js()) { + $state = "CLEAN"; + } + } else { + if ($frame->is_safe_html()) { + $state = "CLEAN"; + } + } + + if ("CLEAN" == $state) { + // Don't print CLEAN instances - No need to update the golden + // file when adding / moving clean instances. + continue; + } + + fprintf($fd, "%-60s %-3s %-8s %s\n", + $view, $frame->line(), $state, $frame->expr()); } } fclose($fd); @@ -280,7 +280,7 @@ class Xss_Security_Test extends Unit_Test_Case { $canonical = MODPATH . "gallery/tests/xss_data.txt"; exec("diff $canonical $new", $output, $return_value); $this->assert_false( - $return_value, "XSS golden file mismatch. Output:\n" . implode("\n", $output) ); + $return_value, "XSS golden file mismatch. Output:\n" . implode("\n", $output) ); } private static function _create_frame($token, $in_script_block) { @@ -296,9 +296,9 @@ class Xss_Security_Test extends Unit_Test_Case { if (is_array($expected_token)) { for ($i = 0; $i < count($expected_token); $i++) { - if ($expected_token[$i] != $token[$i]) { - return false; - } + if ($expected_token[$i] != $token[$i]) { + return false; + } } return true; } else { diff --git a/modules/server_add/helpers/server_add_event.php b/modules/server_add/helpers/server_add_event.php index 6b21ec2e..b2d55153 100644 --- a/modules/server_add/helpers/server_add_event.php +++ b/modules/server_add/helpers/server_add_event.php @@ -35,7 +35,7 @@ class server_add_event_Core { // turn that into a dropdown if there are two different ways to add things. Do that in a // portable way for now. If we find ourselves duplicating this pattern, we should make an // API method for this. - $add_menu = $menu->get("add_menu"); + $add_menu = $menu->get("add_menu"); $add_menu->append(Menu::factory("dialog") ->id("server_add") ->label(t("Server add")) -- cgit v1.2.3 From 33bcf11e2714f727f16136a1c09926cd5b6c8212 Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Thu, 3 Sep 2009 01:05:03 -0700 Subject: Change the Html_Helper and SafeString tests to change the expeced results based on whether HtmlPurifier module is installed or not --- modules/gallery/tests/Html_Helper_Test.php | 5 +++-- modules/gallery/tests/SafeString_Test.php | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/tests/Html_Helper_Test.php b/modules/gallery/tests/Html_Helper_Test.php index bfce6dcf..8f665e0c 100644 --- a/modules/gallery/tests/Html_Helper_Test.php +++ b/modules/gallery/tests/Html_Helper_Test.php @@ -27,8 +27,9 @@ class Html_Helper_Test extends Unit_Test_Case { public function purify_test() { $safe_string = html::purify("hello

world

"); - $this->assert_equal("hello

world

", - $safe_string); + $expected = + module::is_active("htmlpurifier") ? "hello

world

" : "hello <p >world</p>"; + $this->assert_equal($expected, $safe_string->unescaped()); $this->assert_true($safe_string instanceof SafeString); } diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index 0895b7dd..37a1865f 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -91,7 +91,9 @@ class SafeString_Test extends Unit_Test_Case { public function purify_test() { $safe_string = SafeString::purify("hello

world

"); - $this->assert_equal("hello

world

", $safe_string); + $expected = + module::is_active("htmlpurifier") ? "hello

world

" : "hello <p >world</p>"; + $this->assert_equal($expected, $safe_string->unescaped()); } public function of_fluid_api_test() { -- cgit v1.2.3 From 8f6a120b52360475859c361514500e46698f0e74 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Thu, 3 Sep 2009 08:39:44 -0700 Subject: Ensure that purify isn't applied twice for an already purified SafeString --- modules/gallery/libraries/SafeString.php | 6 +++++- modules/gallery/tests/SafeString_Test.php | 10 +++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php index 800647fa..e6f54add 100644 --- a/modules/gallery/libraries/SafeString.php +++ b/modules/gallery/libraries/SafeString.php @@ -51,7 +51,11 @@ class SafeString_Core { */ static function purify($string) { if ($string instanceof SafeString) { - $string = $string->unescaped(); + if ($string->_is_purified_html) { + return $string; + } else { + $string = $string->unescaped(); + } } $safe_string = self::of_safe_html(self::_purify_for_html($string)); $safe_string->_is_purified_html = true; diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index 37a1865f..57ac87b9 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -93,7 +93,15 @@ class SafeString_Test extends Unit_Test_Case { $safe_string = SafeString::purify("hello

world

"); $expected = module::is_active("htmlpurifier") ? "hello

world

" : "hello <p >world</p>"; - $this->assert_equal($expected, $safe_string->unescaped()); + $this->assert_equal($expected, $safe_string); + } + + public function purify_twice_test() { + $safe_string = SafeString::purify("hello

world

"); + $safe_string_2 = SafeString::purify($safe_string); + $expected = + module::is_active("htmlpurifier") ? "hello

world

" : "hello <p >world</p>"; + $this->assert_equal($expected, $safe_string_2); } public function of_fluid_api_test() { -- cgit v1.2.3 From 1405e8ed9e2003d1b06853bae4ce3413de1910ce Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Thu, 3 Sep 2009 11:29:57 -0700 Subject: Fix tests for new purifier API. --- modules/gallery/tests/SafeString_Test.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index 57ac87b9..fdab5c58 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -91,16 +91,18 @@ class SafeString_Test extends Unit_Test_Case { public function purify_test() { $safe_string = SafeString::purify("hello

world

"); - $expected = - module::is_active("htmlpurifier") ? "hello

world

" : "hello <p >world</p>"; + $expected = method_exists("purifier", "purify") + ? "hello

world

" + : "hello <p >world</p>"; $this->assert_equal($expected, $safe_string); } public function purify_twice_test() { $safe_string = SafeString::purify("hello

world

"); $safe_string_2 = SafeString::purify($safe_string); - $expected = - module::is_active("htmlpurifier") ? "hello

world

" : "hello <p >world</p>"; + $expected = method_exists("purifier", "purify") + ? "hello

world

" + : "hello <p >world</p>"; $this->assert_equal($expected, $safe_string_2); } -- cgit v1.2.3 From c453c0ef8239bc79e484dd3feb9e275e942e9d48 Mon Sep 17 00:00:00 2001 From: Andy Staudacher Date: Fri, 4 Sep 2009 10:11:42 -0700 Subject: Simplifying SafeString a bit: From a XSS HTML security point of view, treat clean() and purify() the same. No longer run a safe HTML string through the HTML purifier (since it's already marked as safe). This also addresses the issue of calling purify() when no purifier is installed. In that case, we'd run clean() on a clean string (double HTML encoding). If this approach doesn't work out, we can still modify the fallback code of purify() to check if the string is already clean before calling clean() instead of purify(). --- modules/gallery/libraries/SafeString.php | 11 ++--------- modules/gallery/tests/SafeString_Test.php | 6 ++++++ 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'modules/gallery/tests/SafeString_Test.php') diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php index 3328fed5..ba3a8ffd 100644 --- a/modules/gallery/libraries/SafeString.php +++ b/modules/gallery/libraries/SafeString.php @@ -24,13 +24,11 @@ class SafeString_Core { private $_raw_string; protected $_is_safe_html = false; - protected $_is_purified_html = false; /** Constructor */ function __construct($string) { if ($string instanceof SafeString) { $this->_is_safe_html = $string->_is_safe_html; - $this->_is_purified_html = $string->_is_purified_html; $string = $string->unescaped(); } $this->_raw_string = (string) $string; @@ -49,14 +47,13 @@ class SafeString_Core { */ static function purify($string) { if ($string instanceof SafeString) { - if ($string->_is_purified_html) { + if ($string->_is_safe_html) { return $string; } else { $string = $string->unescaped(); } } $safe_string = self::of_safe_html(self::_purify_for_html($string)); - $safe_string->_is_purified_html = true; return $safe_string; } @@ -135,11 +132,7 @@ class SafeString_Core { * @return the string escaped for use in HTML. */ function purified_html() { - if ($this->_is_purified_html) { - return $this; - } else { - return self::purify($this); - } + return self::purify($this); } /** diff --git a/modules/gallery/tests/SafeString_Test.php b/modules/gallery/tests/SafeString_Test.php index fdab5c58..2c07d934 100644 --- a/modules/gallery/tests/SafeString_Test.php +++ b/modules/gallery/tests/SafeString_Test.php @@ -106,6 +106,12 @@ class SafeString_Test extends Unit_Test_Case { $this->assert_equal($expected, $safe_string_2); } + public function purify_safe_html_test() { + $safe_string = SafeString::of_safe_html("hello

world

"); + $actual = SafeString::purify($safe_string); + $this->assert_equal("hello

world

", $actual); + } + public function of_fluid_api_test() { $escaped_string = SafeString::of("Foo's bar")->for_js(); $this->assert_equal('"Foo\'s bar"', $escaped_string); -- cgit v1.2.3