Squash bugs
[squirrelmail.git] / functions / strings.php
index 3ea6ea3df42fb889ef4a8224ff77c371e272b21e..d03163b0f4ab56b9b61cca66d15e9030eabd9b7d 100644 (file)
@@ -6,7 +6,7 @@
  * This code provides various string manipulation functions that are
  * used by the rest of the SquirrelMail code.
  *
- * @copyright 1999-2012 The SquirrelMail Project Team
+ * @copyright 1999-2016 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -914,48 +914,6 @@ function sq_is8bit($string,$charset='') {
      * stores control symbols in those charsets.
      * Use preg_match instead of ereg in order to avoid problems
      * with mbstring overloading
-NOTES:
-NOTES:
-        37 (base 8) =  31 (base 10) (LAST CONTROL CHAR)
-        40 (base 8) =  32 (base 10) (FIRST PRINTABLE ASCII)
-       176 (base 8) = 126 (base 10) (LAST PRINTABLE ASCII)
-       177 (base 8) = 127 (base 10) (DEL)
-       200 (base 8) = 128 (base 10)
-       237 (base 8) = 159 (base 10)
-       240 (base 8) = 160 (base 10) (FIRST EXTRA PRINTABLE)
-       377 (base 8) = 255 (base 10) (LAST EXTRA PRINTABLE)
-       400 (base 8) = 256 (base 10)
-
-       Traditional ASCII                          0 - 127 (octal   0 - 177)
-       Printable ASCII                           32 - 126 (octal  40 - 176)
-       Additional Printables for ISO Latin 1    160 - 255 (octal 240 - 377)
-
-       240 (160) is the first character of the extra 7-bit printable characer
-       range, sometimes used as the no-break space, but the regular expression
-       ranges are broken up at 240 only because RH 7.2 PHP seemed to have
-       problems otherwise - this is a PHP/preg issue, NOT a charset issue
-
-       So supposedly printable chars in an 8859 charset are 32-126 (octal 40-176)
-       and 160/161-255 (octal 240/241-377))
-
-       So checking for the range between the two makes sense (128-159 or octal 200-237)
-         (wait, no, to skip DEL too, it's 127-159 (octal 177-237))
-
-       But why not for 0-31 (octal 0-37) and DEL (127 or 177 octal)????
-         (or do we need a new fxn that detects *printable* 7-bit chars?)
-            (if we do, note that some control characters are "printable",
-             notably the CR, LF and TAB characters)
-       
-       And why is 241-377 octal considered 8-bit for iso 8859???  Isn't it
-       the opposite for iso 8859????   aren't these 7 bit characters?
-       see http://www.cs.tut.fi/~jkorpela/chars.html#latin1
-         Uh, well, anything more than 127 (octal 177) takes 8 bits to represent
-         but errrrr, these are simple non-multibyte characters, right?  but
-         maybe this "is 8-bit" business is NOT the same as "is multibyte"????
-
-         That begs the question how this fxn is actually used - what's its purpose?
-         (is it being misused in some places?)
-
      */
     if (preg_match("/^iso-8859/i",$charset)) {
         $needle='/\240|[\241-\377]/';
@@ -1643,10 +1601,12 @@ function sm_generate_security_token($force_generate_new=FALSE)
   * @param string  $token           The token to validate
   * @param int     $validity_period The number of seconds tokens are valid
   *                                 for (set to zero to remove valid tokens
-  *                                 after only one use; use 3600 to allow
-  *                                 tokens to be reused for an hour)
-  *                                 (OPTIONAL; default is to only allow tokens
-  *                                 to be used once)
+  *                                 after only one use; set to -1 to allow
+  *                                 indefinite re-use (but still subject to
+  *                                 $max_token_age_days - see elsewhere);
+  *                                 use 3600 to allow tokens to be reused for
+  *                                 an hour) (OPTIONAL; default is to only
+  *                                 allow tokens to be used once)
   *                                 NOTE this is unrelated to $max_token_age_days
   *                                 or rather is an additional time constraint on
   *                                 tokens that allows them to be re-used (or not)
@@ -1691,9 +1651,11 @@ function sm_validate_security_token($token, $validity_period=0, $show_error=FALS
    $timestamp = $tokens[$token];
 
    // whether valid or not, we want to remove it from
-   // user prefs if it's old enough
+   // user prefs if it's old enough (unless requested to
+   // bypass this (in which case $validity_period is -1))
    //
-   if ($timestamp < $now - $validity_period)
+   if ($validity_period >= 0
+    && $timestamp < $now - $validity_period)
    {
       unset($tokens[$token]);
       setPref($data_dir, $username, 'security_tokens', serialize($tokens));
@@ -1716,3 +1678,43 @@ function sm_validate_security_token($token, $validity_period=0, $show_error=FALS
 
 }
 
+/**
+  * Wrapper for PHP's htmlspecialchars() that
+  * attempts to add the correct character encoding
+  *
+  * @param string $string The string to be converted
+  * @param int $flags A bitmask that controls the behavior of htmlspecialchars()
+  *                   (See http://php.net/manual/function.htmlspecialchars.php )
+  *                   (OPTIONAL; default ENT_COMPAT, ENT_COMPAT | ENT_SUBSTITUTE for PHP >=5.4)
+  * @param string $encoding The character encoding to use in the conversion
+  *                         (OPTIONAL; default automatic detection)
+  * @param boolean $double_encode Whether or not to convert entities that are
+  *                               already in the string (only supported in
+  *                               PHP 5.2.3+) (OPTIONAL; default TRUE)
+  *
+  * @return string The converted text
+  *
+  */
+function sm_encode_html_special_chars($string, $flags=ENT_COMPAT,
+                                      $encoding=NULL, $double_encode=TRUE)
+{
+   if (!$encoding)
+   {
+      global $default_charset;
+      if ($default_charset == 'iso-2022-jp')
+         $default_charset = 'EUC-JP';
+      $encoding = $default_charset;
+   }
+
+   if (check_php_version(5, 2, 3)) {
+      // Replace invalid characters with a symbol instead of returning
+      // empty string for the entire to be encoded string.
+      if (check_php_version(5, 4, 0) && $flags == ENT_COMPAT) {
+         $flags = $flags | ENT_SUBSTITUTE;
+      }
+      return htmlspecialchars($string, $flags, $encoding, $double_encode);
+   }
+
+   return htmlspecialchars($string, $flags, $encoding);
+}
+