summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Andreev <narf@devilix.net>2014-07-07 13:11:26 +0200
committerAndrey Andreev <narf@devilix.net>2014-07-07 13:11:26 +0200
commit6500bc77232657141dbc34aa3c840dd9e205b84f (patch)
treee2d1c8bc2757e192a832a858aacc3ca6b42e34f2
parent5b3fe7c4af5e08e17480b911fbfa8cf0ef6475c0 (diff)
Add a backport (compat) for quoted_printable_encode()
-rw-r--r--system/core/compat/standard.php92
-rw-r--r--tests/codeigniter/core/compat/standard_test.php115
-rw-r--r--user_guide_src/source/changelog.rst2
-rw-r--r--user_guide_src/source/general/compatibility_functions.rst11
4 files changed, 216 insertions, 4 deletions
diff --git a/system/core/compat/standard.php b/system/core/compat/standard.php
index 6380fa1e8..afe9e9852 100644
--- a/system/core/compat/standard.php
+++ b/system/core/compat/standard.php
@@ -289,5 +289,93 @@ if ( ! function_exists('array_replace_recursive'))
}
}
-/* End of file array.php */
-/* Location: ./system/core/compat/array.php */ \ No newline at end of file
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('quoted_printable_encode'))
+{
+ /**
+ * quoted_printable_encode()
+ *
+ * @link http://php.net/quoted_printable_encode
+ * @param string $str
+ * @return string
+ */
+ function quoted_printable_encode($str)
+ {
+ if (strlen($str) === 0)
+ {
+ return '';
+ }
+ elseif (in_array($type = gettype($str), array('array', 'object'), TRUE))
+ {
+ if ($type === 'object' && method_exists($str, '__toString'))
+ {
+ $str = (string) $str;
+ }
+ else
+ {
+ trigger_error('quoted_printable_encode() expects parameter 1 to be string, '.$type.' given', E_USER_WARNING);
+ return NULL;
+ }
+ }
+
+ if (function_exists('imap_8bit'))
+ {
+ return imap_8bit($str);
+ }
+
+ $i = $lp = 0;
+ $output = '';
+ $hex = '0123456789ABCDEF';
+ $length = (extension_loaded('mbstring') && ini_get('mbstring.func_overload'))
+ ? mb_strlen($str, '8bit')
+ : strlen($str);
+
+ while ($length--)
+ {
+ if ((($c = $str[$i++]) === "\015") && isset($str[$i]) && ($str[$i] === "\012") && $length > 0)
+ {
+ $output .= "\015".$str[$i++];
+ $length--;
+ $lp = 0;
+ continue;
+ }
+
+ if (
+ ctype_cntrl($c)
+ OR (ord($c) === 0x7f)
+ OR (ord($c) & 0x80)
+ OR ($c === '=')
+ OR ($c === ' ' && isset($str[$i]) && $str[$i] === "\015")
+ )
+ {
+ if (
+ (($lp += 3) > 75 && ord($c) <= 0x7f)
+ OR (ord($c) > 0x7f && ord($c) <= 0xdf && ($lp + 3) > 75)
+ OR (ord($c) > 0xdf && ord($c) <= 0xef && ($lp + 6) > 75)
+ OR (ord($c) > 0xef && ord($c) <= 0xf4 && ($lp + 9) > 75)
+ )
+ {
+ $output .= "=\015\012";
+ $lp = 3;
+ }
+
+ $output .= '='.$hex[ord($c) >> 4].$hex[ord($c) & 0xf];
+ continue;
+ }
+
+ if ((++$lp) > 75)
+ {
+ $output .= "=\015\012";
+ $lp = 1;
+ }
+
+ $output .= $c;
+ }
+
+ return $output;
+ }
+}
+
+/* End of file standard.php */
+/* Location: ./system/core/compat/standard.php */ \ No newline at end of file
diff --git a/tests/codeigniter/core/compat/standard_test.php b/tests/codeigniter/core/compat/standard_test.php
index 8c7e7313a..a3a6d9552 100644
--- a/tests/codeigniter/core/compat/standard_test.php
+++ b/tests/codeigniter/core/compat/standard_test.php
@@ -20,6 +20,7 @@ class standard_test extends CI_TestCase {
{
$this->assertTrue(function_exists('array_replace'));
$this->assertTrue(function_exists('array_replace_recursive'));
+ $this->assertTrue(function_exists('quoted_printable_encode'));
}
}
@@ -431,6 +432,113 @@ class standard_test extends CI_TestCase {
array_replace_recursive($array1, $array2)
);
}
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * quoted_printable_encode() tests
+ *
+ * Borrowed from PHP's own tests
+ *
+ * @depends test_bootstrap
+ */
+ public function test_quoted_printable_encode()
+ {
+ if (is_php('5.3'))
+ {
+ return $this->markTestSkipped('quoted_printable_encode() is already available on PHP 5.3');
+ }
+
+
+ // These are actually imap_8bit() tests:
+ $this->assertEquals("String with CRLF at end=20\r\n", quoted_printable_encode("String with CRLF at end \r\n"));
+ // ext/imap/tests/imap_8bit_basic.phpt says for this line:
+ // NB this appears to be a bug in cclient; a space at end of string should be encoded as =20
+ $this->assertEquals("String with space at end ", quoted_printable_encode("String with space at end "));
+ $this->assertEquals("String with tabs =09=09 in middle", quoted_printable_encode("String with tabs \t\t in middle"));
+ $this->assertEquals("String with tab at end =09", quoted_printable_encode("String with tab at end \t"));
+ $this->assertEquals("=00=01=02=03=04=FE=FF=0A=0D", quoted_printable_encode("\x00\x01\x02\x03\x04\xfe\xff\x0a\x0d"));
+
+ // And these are from ext/standard/tests/strings/quoted_printable_encode_002.phpt:
+ $this->assertEquals(
+ "=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=\r\n"
+ ."=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00=00",
+ $d = quoted_printable_encode(str_repeat("\0", 200))
+ );
+ $this->assertEquals(str_repeat("\x0", 200), quoted_printable_decode($d));
+ $this->assertEquals(
+ "=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=\r\n"
+ ."=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=\r\n"
+ ."=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=\r\n"
+ ."=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=\r\n"
+ ."=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=\r\n"
+ ."=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=\r\n"
+ ."=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=\r\n"
+ ."=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=\r\n"
+ ."=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =\r\n"
+ ."=D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=\r\n"
+ ."=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=\r\n"
+ ."=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=\r\n"
+ ."=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=\r\n"
+ ."=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=\r\n"
+ ."=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=\r\n"
+ ."=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=\r\n"
+ ."=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=\r\n"
+ ."=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=\r\n"
+ ."=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=\r\n"
+ ."=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =\r\n"
+ ."=D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=\r\n"
+ ."=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=\r\n"
+ ."=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=\r\n"
+ ."=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=\r\n"
+ ."=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=\r\n"
+ ."=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=\r\n"
+ ."=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=\r\n"
+ ."=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=\r\n"
+ ."=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=\r\n"
+ ."=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=\r\n"
+ ."=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=\r\n"
+ ."=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =\r\n"
+ ."=D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=\r\n"
+ ."=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=\r\n"
+ ."=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=\r\n"
+ ."=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=\r\n"
+ ."=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=\r\n"
+ ."=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=\r\n"
+ ."=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=\r\n"
+ ."=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=\r\n"
+ ."=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=\r\n"
+ ."=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=\r\n"
+ ."=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =\r\n"
+ ."=D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=\r\n"
+ ."=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=\r\n"
+ ."=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=\r\n"
+ ."=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=\r\n"
+ ."=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=\r\n"
+ ."=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=\r\n"
+ ."=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=\r\n"
+ ."=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=\r\n"
+ ."=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=\r\n"
+ ."=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=\r\n"
+ ."=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=\r\n"
+ ."=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =\r\n"
+ ."=D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=\r\n"
+ ."=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=\r\n"
+ ."=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=\r\n"
+ ."=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=8E=D0=BD=D0=B8=\r\n"
+ ."=D0=BA=D0=BE=D0=B4=D0=B5=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0 =D0=B2 =D1=\r\n"
+ ."=8E=D0=BD=D0=B8=D0=BA=D0=BE=D0=B4=D0=B5",
+ $d = quoted_printable_encode(str_repeat('строка в юникоде', 50))
+ );
+ $this->assertEquals(str_repeat('строка в юникоде', 50), quoted_printable_decode($d));
+ $this->assertEquals('this is a foo', quoted_printable_encode(new FooObject()));
+ }
}
// ------------------------------------------------------------------------
@@ -457,5 +565,12 @@ class FooHex {
{
return '010203';
}
+}
+class FooObject
+{
+ public function __toString()
+ {
+ return 'this is a foo';
+ }
} \ No newline at end of file
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 4bb2a3ee1..987e466d5 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -530,7 +530,7 @@ Release Date: Not Released
- `Multibyte String <http://php.net/mbstring>`_ (limited support).
- `Hash <http://php.net/hash>`_ (``hash_equals()``, ``hash_pbkdf2()``).
- `Password Hashing <http://php.net/password>`_.
- - `Standard Functions ``array_column()``, ``array_replace()``, ``array_replace_recursive()``, ``hexbin()``.
+ - `Standard Functions ``array_column()``, ``array_replace()``, ``array_replace_recursive()``, ``hex2bin()``, ``quoted_printable_encode()``.
- Removed ``CI_CORE`` boolean constant from *CodeIgniter.php* (no longer Reactor and Core versions).
- Log Library will now try to create the **log_path** directory if it doesn't exist.
diff --git a/user_guide_src/source/general/compatibility_functions.rst b/user_guide_src/source/general/compatibility_functions.rst
index 0dc87804b..aee9b1ef0 100644
--- a/user_guide_src/source/general/compatibility_functions.rst
+++ b/user_guide_src/source/general/compatibility_functions.rst
@@ -252,4 +252,13 @@ Function reference
:rtype: string
For more information, please refer to the `PHP manual for hex2bin()
- <http://php.net/hex2bin>`_. \ No newline at end of file
+ <http://php.net/hex2bin>`_.
+
+.. function:: quoted_printable_encode($str)
+
+ :param string $str: Input string
+ :returns: 8bit-encoded string
+ :rtype: string
+
+ For more information, please refer to the `PHP manual for
+ quoted_printable_encode() <http://php.net/quoted_printable_encode>`_. \ No newline at end of file