summaryrefslogtreecommitdiff
path: root/modules/gallery/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery/libraries')
-rw-r--r--modules/gallery/libraries/I18n.php20
-rw-r--r--modules/gallery/libraries/MY_ORM.php4
-rw-r--r--modules/gallery/libraries/SafeString.php177
3 files changed, 195 insertions, 6 deletions
diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php
index d0531b9a..c3336052 100644
--- a/modules/gallery/libraries/I18n.php
+++ b/modules/gallery/libraries/I18n.php
@@ -89,6 +89,12 @@ class I18n_Core {
/**
* Translates a localizable message.
+ *
+ * Security:
+ * The returned string is safe for use in HTML (it contains a safe subset of HTML and
+ * interpolation parameters are converted to HTML entities).
+ * For use in JavaScript, please call ->for_js() on it.
+ *
* @param $message String|array The message to be translated. E.g. "Hello world"
* or array("one" => "One album", "other" => "%count albums")
* @param $options array (optional) Options array for key value pairs which are used
@@ -115,7 +121,7 @@ class I18n_Core {
$entry = $this->interpolate($locale, $entry, $values);
- return $entry;
+ return SafeString::of_safe_html($entry);
}
private function lookup($locale, $message) {
@@ -184,17 +190,19 @@ class I18n_Core {
return is_array($message);
}
- private function interpolate($locale, $string, $values) {
+ private function interpolate($locale, $string, $key_values) {
// TODO: Handle locale specific number formatting.
// Replace x_y before replacing x.
- krsort($values, SORT_STRING);
+ krsort($key_values, SORT_STRING);
$keys = array();
- foreach (array_keys($values) as $key) {
+ $values = array();
+ foreach ($key_values as $key => $value) {
$keys[] = "%$key";
+ $values[] = new SafeString($value);
}
- return str_replace($keys, array_values($values), $string);
+ return str_replace($keys, $values, $string);
}
private function pluralize($locale, $entry, $count) {
@@ -419,4 +427,4 @@ class I18n_Core {
return $count == 1 ? 'one' : 'other';
}
}
-} \ No newline at end of file
+}
diff --git a/modules/gallery/libraries/MY_ORM.php b/modules/gallery/libraries/MY_ORM.php
index de8adc1d..2c9ad1d7 100644
--- a/modules/gallery/libraries/MY_ORM.php
+++ b/modules/gallery/libraries/MY_ORM.php
@@ -43,6 +43,10 @@ class ORM extends ORM_Core {
$this->original = clone $this;
}
+ if ($value instanceof SafeString) {
+ $value = $value->unescaped();
+ }
+
return parent::__set($column, $value);
}
diff --git a/modules/gallery/libraries/SafeString.php b/modules/gallery/libraries/SafeString.php
new file mode 100644
index 00000000..9614a213
--- /dev/null
+++ b/modules/gallery/libraries/SafeString.php
@@ -0,0 +1,177 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * Safe string representation (regarding security - cross site scripting).
+ */
+class SafeString_Core {
+ private $_raw_string;
+ protected $_is_safe_html = false;
+ protected $_is_purified_html = false;
+
+ private static $_purifier = null;
+
+ /** 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;
+ }
+
+ /**
+ * Factory method returning a new SafeString instance for the given string.
+ */
+ static function of($string) {
+ return new SafeString($string);
+ }
+
+ /**
+ * Factory method returning a new SafeString instance after HTML purifying
+ * the given string.
+ */
+ 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;
+ }
+
+ /**
+ * Safe for use in HTML.
+ * @see #for_html()
+ */
+ function __toString() {
+ if ($this->_is_safe_html) {
+ return $this->_raw_string;
+ } else {
+ return self::_escape_for_html($this->_raw_string);
+ }
+ }
+
+ /**
+ * Safe for use in HTML.
+ *
+ * Example:<pre>
+ * <div><?= $php_var ?>
+ * </pre>
+ * @return the string escaped for use in HTML.
+ */
+ function for_html() {
+ return $this;
+ }
+
+ /**
+ * Safe for use in JavaScript.
+ *
+ * Example:<pre>
+ * <script type="text/javascript>"
+ * var some_js_var = "<?= $php_var->for_js() ?>";
+ * </script>
+ * </pre>
+ * @return the string escaped for use in JavaScript.
+ */
+ function for_js() {
+ 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:<pre>
+ * <a title="<?= $php_var->for_html_attr() ?>">;
+ * </script>
+ * </pre>
+ * @return the string escaped for use in HTML attributes.
+ */
+ function for_html_attr() {
+ $string = (string) $this->for_html();
+ return strtr($string,
+ array("'"=>"&#039;",
+ '"'=>'&quot;'));
+ }
+
+ /**
+ * Safe for use HTML (purified HTML)
+ *
+ * Example:<pre>
+ * <div><?= $php_var->purified_html() ?>
+ * </pre>
+ * @return the string escaped for use in HTML.
+ */
+ function purified_html() {
+ if ($this->_is_purified_html) {
+ return $this;
+ } else {
+ return self::purify($this);
+ }
+ }
+
+ /**
+ * Returns the raw, unsafe string. Do not use lightly.
+ */
+ function unescaped() {
+ return $this->_raw_string;
+ }
+
+ // Escapes special HTML chars ("<", ">", "&", etc.) to HTML entities.
+ private static function _escape_for_html($dirty_html) {
+ 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)) {
+ require_once(dirname(__file__) . "/../lib/HTMLPurifier/HTMLPurifier.auto.php");
+ $config = HTMLPurifier_Config::createDefault();
+ foreach (Kohana::config('purifier') as $category => $key_value) {
+ foreach ($key_value as $key => $value) {
+ $config->set("$category.$key", $value);
+ }
+ }
+ self::$_purifier = new HTMLPurifier($config);
+ }
+ return self::$_purifier->purify($dirty_html);
+ }
+}