Move test_ext_fb to php

Esse commit está contido em:
Jordan DeLong
2013-06-14 15:59:32 -07:00
commit de Sara Golemon
commit 6c7cb9f55e
16 arquivos alterados com 6741 adições e 424 exclusões
-1
Ver Arquivo
@@ -48,7 +48,6 @@
#include "hphp/test/ext/test_ext_debugger.h"
#include "hphp/test/ext/test_ext_domdocument.h"
#include "hphp/test/ext/test_ext_error.h"
#include "hphp/test/ext/test_ext_fb.h"
#include "hphp/test/ext/test_ext_file.h"
#include "hphp/test/ext/test_ext_function.h"
#include "hphp/test/ext/test_ext_hash.h"
-374
Ver Arquivo
@@ -1,374 +0,0 @@
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#include "hphp/test/ext/test_ext_fb.h"
#include "hphp/runtime/ext/ext_fb.h"
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/runtime/ext/ext_iconv.h"
///////////////////////////////////////////////////////////////////////////////
bool TestExtFb::RunTests(const std::string &which) {
bool ret = true;
DECLARE_TEST_FUNCTIONS("function test($s1) {"
" return $s1;"
"}");
RUN_TEST(test_fb_compact_serialize);
RUN_TEST(test_fb_compact_unserialize);
RUN_TEST(test_fb_thrift_serialize);
RUN_TEST(test_fb_thrift_unserialize);
RUN_TEST(test_fb_rename_function);
RUN_TEST(test_fb_utf8ize);
RUN_TEST(test_fb_utf8_strlen);
RUN_TEST(test_fb_utf8_strlen_deprecated);
RUN_TEST(test_fb_utf8_substr);
RUN_TEST(test_fb_call_user_func_safe);
RUN_TEST(test_fb_call_user_func_safe_return);
RUN_TEST(test_fb_call_user_func_array_safe);
RUN_TEST(test_fb_load_local_databases);
RUN_TEST(test_fb_parallel_query);
RUN_TEST(test_fb_crossall_query);
return ret;
}
///////////////////////////////////////////////////////////////////////////////
#define fb_cs_test(v) do { \
Variant ret; \
Variant v_ = v; \
Variant s_ = f_fb_compact_serialize(v_); \
VERIFY(s_.isString()); \
String ss_ = s_.toString(); \
VERIFY(!ss_.empty()); \
/* check high bit of first character always set */ \
VERIFY(ss_[0] & 0x80); \
VS(f_fb_compact_unserialize(s_, ref(ret)), v_); \
VERIFY(same(ret, true)); \
ret = uninit_null(); \
VS(f_fb_unserialize(s_, ref(ret)), v_); \
VERIFY(same(ret, true)); \
} while(0)
bool TestExtFb::test_fb_compact_serialize() {
fb_cs_test(uninit_null());
fb_cs_test(true);
fb_cs_test(false);
fb_cs_test(1234.5678);
fb_cs_test("");
fb_cs_test("a");
fb_cs_test("\0");
fb_cs_test("\0 a");
fb_cs_test("0123012301230123");
fb_cs_test("0123012301230123a");
fb_cs_test("012301230123012");
fb_cs_test(Array());
fb_cs_test(CREATE_VECTOR1(12345));
fb_cs_test(CREATE_VECTOR3(12345,"abc",0.1234));
fb_cs_test(CREATE_MAP1(1, 12345));
fb_cs_test(CREATE_MAP3(1, 12345, "a", 123124, "sdf", 0.1234));
fb_cs_test(CREATE_VECTOR1(CREATE_VECTOR1("a")));
fb_cs_test(CREATE_VECTOR2(1, CREATE_VECTOR1("a")));
fb_cs_test(CREATE_VECTOR2(CREATE_VECTOR1("a"), 1));
fb_cs_test(CREATE_VECTOR2(CREATE_VECTOR1("a"), CREATE_VECTOR1(1)));
// Test skips
fb_cs_test(CREATE_MAP3(0, "a", 1, "b", 3, "c"));
fb_cs_test(CREATE_MAP3(1, "a", 2, "b", 3, "c"));
fb_cs_test(CREATE_MAP3(0, "a", 2, "b", 3, "c"));
fb_cs_test(CREATE_MAP1(3, "a"));
// Test for overflow
fb_cs_test(CREATE_MAP1((int64_t)((1ULL << 63) - 1), "a"));
// Test each power of two, +/- 1 and the negatives of them
// Test a single number and packed inside an array
for (int i = 0; i < 64; ++i) {
int64_t n = (1ULL << i);
fb_cs_test(n); fb_cs_test(CREATE_VECTOR1(n));
fb_cs_test(n-1); fb_cs_test(CREATE_VECTOR1(n-1));
fb_cs_test(n+1); fb_cs_test(CREATE_VECTOR1(n+1));
fb_cs_test(-n); fb_cs_test(CREATE_VECTOR1(-n));
fb_cs_test(-n-1); fb_cs_test(CREATE_VECTOR1(-n-1));
fb_cs_test(-n+1); fb_cs_test(CREATE_VECTOR1(-n+1));
}
// Test vector code (PHP can't create those, but they might come form
// C++ code in serialized strings)
String s("\xfe\x01\x02\x03\xfc"); // VECTOR, 1, 2, 3, STOP
Variant ret;
VS(f_fb_compact_unserialize(s, ref(ret)), CREATE_VECTOR3(1, 2, 3));
return Count(true);
}
#undef fb_cs_test
bool TestExtFb::test_fb_compact_unserialize() {
// tested above
return Count(true);
}
///////////////////////////////////////////////////////////////////////////////
bool TestExtFb::test_fb_thrift_serialize() {
Variant ret;
VS(f_fb_thrift_unserialize(f_fb_thrift_serialize("test"), ref(ret)), "test");
VERIFY(same(ret, true));
ret = uninit_null();
VS(f_fb_thrift_unserialize(f_fb_thrift_serialize(CREATE_VECTOR1("test")),
ref(ret)),
CREATE_VECTOR1("test"));
VERIFY(same(ret, true));
return Count(true);
}
bool TestExtFb::test_fb_thrift_unserialize() {
// tested above
return Count(true);
}
bool TestExtFb::test_fb_rename_function() {
// tested in TestCodeRun
return Count(true);
}
// This string includes an invalid UTF-8 sequence. The first byte
// suggests this is a three-byte UTF-8 sequence, but it's not valid.
//
// The legacy fb_utf8ize() implementation used to treat this three-byte
// sequence as two invalid code points followed by a valid ASCII character.
// It transforms the three bytes to the three code point sequence
// \xef\xbf\xbd\xef\xbf\xbd\x28.
//
// ICU treats this three-byte sequence as one invalid two-byte code point
// followed by a valid ASCII character. An ICU-based fb_utf8ize()
// implementation will transform the three bytes to the two code point
// sequence \xef\xbf\xbd\x28.
static const char *INVALID_UTF_8_STRING = "\xe2\x82\x28";
bool TestExtFb::test_fb_utf8ize() {
for (int i = 0; i < 2; i++) {
RuntimeOption::Utf8izeReplace = (i == 0);
{
Variant s = "hon\xE7k";
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "hon\uFFFDk");
} else {
VS(s, "honk");
}
}
{
Variant s = "test\xE0\xB0\xB1\xE0";
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "test\xE0\xB0\xB1\uFFFD");
} else {
VS(s, "test\xE0\xB0\xB1");
}
}
{
Variant s = "test\xE0\xB0\xB1\xE0\xE0";
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "test\xE0\xB0\xB1\uFFFD\uFFFD");
} else {
VS(s, "test\xE0\xB0\xB1");
}
}
{
Variant s = "\xfc";
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "\uFFFD");
} else {
VS(s, "");
}
}
{
Variant s = "\xfc\xfc";
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "\uFFFD\uFFFD");
} else {
VS(s, "");
}
}
{
// We intentionally consider null bytes invalid sequences.
Variant s = String("abc\0def", 7, AttachLiteral);
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "abc\uFFFD""def");
} else {
VS(s, "abcdef");
}
}
{
// ICU treats this as as two code points.
// The old implementation treated this as three code points.
Variant s = INVALID_UTF_8_STRING;
VERIFY(f_fb_utf8ize(ref(s)));
if (RuntimeOption::Utf8izeReplace) {
VS(s, "\uFFFD""\x28");
} else {
VS(s, "\x28");
}
}
}
return Count(true);
}
// fb_utf8_strlen_deprecated() returns byte count on invalid input.
bool TestExtFb::test_fb_utf8_strlen_deprecated() {
// Invalid UTF-8 sequence fails.
VS(f_fb_utf8_strlen_deprecated(INVALID_UTF_8_STRING), 3);
return Count(true);
}
bool TestExtFb::test_fb_utf8_strlen() {
VS(f_fb_utf8_strlen(""), 0);
VS(f_fb_utf8_strlen("a"), 1);
VS(f_fb_utf8_strlen("ab"), 2);
// Valid UTF-8 sequence returns code point count.
VS(f_fb_utf8_strlen("\ub098\ub294"), 2);
VS(f_fb_utf8_strlen(INVALID_UTF_8_STRING), 2);
for (int i = 0; i < 2; i++) {
// Test utf8ize() handling of invalid UTF-8 sequences and how
// fb_utf8_strlen() counts them.
// RuntimeOption::Utf8izeReplace set to non-zero value replaces invalid
// bytes, including '\0' with a special UTF-8 code point: "\uFFFD".
// RuntimeOption::Utf8izeReplace set to zero deletes the invalid
// byte then continues parsing.
RuntimeOption::Utf8izeReplace = (i == 0);
{
Variant s = String("abc\0def", 7, AttachLiteral);
VS(s.toString().size(), 7);
VS(f_fb_utf8_strlen(s), 7);
f_fb_utf8ize(ref(s)); // Modifies s
int ret = s.toString().size();
if (RuntimeOption::Utf8izeReplace) {
VS(ret, 9); // '\0' converted to "\uFFFD"
} else {
VS(ret, 6); // '\0' deleted from s
}
ret = f_fb_utf8_strlen(s);
if (RuntimeOption::Utf8izeReplace) {
VS(ret, 7); // '\0' and "\uFFFD" are both one code point, so no change
} else {
VS(ret, 6); // '\0' deleted, so one fewer code point
}
}
}
return Count(true);
}
bool TestExtFb::test_fb_utf8_substr() {
// Falsey inputs
VS(f_fb_utf8_substr("", 0, 0), false);
VS(f_fb_utf8_substr("", 0, 1), false);
VS(f_fb_utf8_substr("hon\xE7k", 0, INT_MAX), "hon\uFFFDk");
VS(f_fb_utf8_substr("hon\xE7k", 0, 3), "hon"); // Never hits invalid byte
VS(f_fb_utf8_substr("hon\xE7k", -4, INT_MAX), "on\uFFFDk");
// Common cases
VS(f_fb_utf8_substr("X", 0, 1), "X");
VS(f_fb_utf8_substr("Hello", 0, INT_MAX), "Hello");
VS(f_fb_utf8_substr("Hello", 1, 2), "el");
VS(f_fb_utf8_substr("Pr\u00DC\u00DDx", 2, 2), "\u00DC\u00DD");
// Negative start
VS(f_fb_utf8_substr("abcdef", -1, INT_MAX), "f");
VS(f_fb_utf8_substr("abcdef", -2, INT_MAX), "ef");
VS(f_fb_utf8_substr("abcdef", -3, 1), "d");
VS(f_fb_utf8_substr("", -1, 1), false);
VS(f_fb_utf8_substr("X", -1, 1), "X");
VS(f_fb_utf8_substr("XY", -1, 1), "Y");
VS(f_fb_utf8_substr("Pr\u00DC\u00DDx", -3, 2), "\u00DC\u00DD");
// Negative lengths
VS(f_fb_utf8_substr("abcdef", 0, -1), "abcde");
VS(f_fb_utf8_substr("abcdef", 2, -1), "cde");
VS(f_fb_utf8_substr("abcdef", 4, -4), false); // nothing to return
VS(f_fb_utf8_substr("abcdef", -3, -1), "de");
// Invalid sequence
VS(f_fb_utf8_substr(INVALID_UTF_8_STRING, 0), "\uFFFD\x28");
return Count(true);
}
bool TestExtFb::test_fb_call_user_func_safe() {
{
Variant ret = f_fb_call_user_func_safe
(1, "TEst", CREATE_VECTOR1("param"));
VS(ret, CREATE_VECTOR2(true, "param"));
}
{
Variant ret = f_fb_call_user_func_safe
(1, "NonTEst", CREATE_VECTOR1("param"));
VS(ret, CREATE_VECTOR2(false, uninit_null()));
}
return Count(true);
}
bool TestExtFb::test_fb_call_user_func_safe_return() {
{
Variant ret = f_fb_call_user_func_safe_return
(1, "TEst", "ok", CREATE_VECTOR1("param"));
VS(ret, "param");
}
{
Variant ret = f_fb_call_user_func_safe_return
(1, "NonTEst", "ok", CREATE_VECTOR1("param"));
VS(ret, "ok");
}
return Count(true);
}
bool TestExtFb::test_fb_call_user_func_array_safe() {
{
Variant ret = f_fb_call_user_func_array_safe
("TEst", CREATE_VECTOR1("param"));
VS(ret, CREATE_VECTOR2(true, "param"));
}
{
Variant ret = f_fb_call_user_func_array_safe
("NonTest", CREATE_VECTOR1("param"));
VS(ret, CREATE_VECTOR2(false, uninit_null()));
}
return Count(true);
}
bool TestExtFb::test_fb_load_local_databases() {
// tested with PHP unit tests
return Count(true);
}
bool TestExtFb::test_fb_parallel_query() {
// tested with PHP unit tests
return Count(true);
}
bool TestExtFb::test_fb_crossall_query() {
// tested with PHP unit tests
return Count(true);
}
-49
Ver Arquivo
@@ -1,49 +0,0 @@
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_TEST_EXT_FB_H_
#define incl_HPHP_TEST_EXT_FB_H_
// >>>>>> Generated by idl.php. Do NOT modify. <<<<<<
#include "hphp/test/ext/test_cpp_ext.h"
///////////////////////////////////////////////////////////////////////////////
class TestExtFb : public TestCppExt {
public:
virtual bool RunTests(const std::string &which);
bool test_fb_compact_serialize();
bool test_fb_compact_unserialize();
bool test_fb_thrift_serialize();
bool test_fb_thrift_unserialize();
bool test_fb_rename_function();
bool test_fb_utf8ize();
bool test_fb_utf8_strlen();
bool test_fb_utf8_strlen_deprecated();
bool test_fb_utf8_substr();
bool test_fb_call_user_func_safe();
bool test_fb_call_user_func_safe_return();
bool test_fb_call_user_func_array_safe();
bool test_fb_load_local_databases();
bool test_fb_parallel_query();
bool test_fb_crossall_query();
};
///////////////////////////////////////////////////////////////////////////////
#endif // incl_HPHP_TEST_EXT_FB_H_
@@ -0,0 +1,41 @@
<?php
function test($s1) { return $s1; }
function a() {
$ret = fb_call_user_func_safe("TEst", "param");
var_dump($ret);
}
function b() {
$ret = fb_call_user_func_safe("NonTEst", "param");
var_dump($ret);
}
function c() {
$ret = fb_call_user_func_safe_return("TEst", "ok", "param");
var_dump($ret);
}
function d() {
$ret = fb_call_user_func_safe_return("NonTEst", "ok", "param");
var_dump($ret);
}
function e() {
$ret = fb_call_user_func_array_safe("TEst", "param");
var_dump($ret);
}
function f() {
$ret = fb_call_user_func_array_safe("NonTest", "param");
var_dump($ret);
}
a();
b();
c();
d();
e();
f();
@@ -0,0 +1,26 @@
array(2) {
[0]=>
bool(true)
[1]=>
string(5) "param"
}
array(2) {
[0]=>
bool(false)
[1]=>
NULL
}
string(5) "param"
string(2) "ok"
array(2) {
[0]=>
bool(true)
[1]=>
string(5) "param"
}
array(2) {
[0]=>
bool(false)
[1]=>
NULL
}
+72
Ver Arquivo
@@ -0,0 +1,72 @@
<?php
function fb_cs_test($v) {
echo "====\n";
$ret = null;
$v_ = $v;
$s_ = fb_compact_serialize($v_);
var_dump(is_string($s_));
$ss_ = $s_;
var_dump(!empty($ss_));
/* check high bit of first character always set */
var_dump(preg_match("/^[\x80-\xff]/", $ss_));
var_dump(fb_compact_unserialize($s_, $ret) === $v_);
var_dump($ret === true);
$ret = null;
var_dump(fb_unserialize($s_, $ret) === $v_);
var_dump($ret === true);
}
function main() {
fb_cs_test(null);
fb_cs_test(true);
fb_cs_test(false);
fb_cs_test(1234.5678);
fb_cs_test("");
fb_cs_test("a");
fb_cs_test("\0");
fb_cs_test("\0 a");
fb_cs_test("0123012301230123");
fb_cs_test("0123012301230123a");
fb_cs_test("012301230123012");
fb_cs_test(array());
fb_cs_test(array(12345));
fb_cs_test(array(12345,"abc",0.1234));
fb_cs_test(array(1 => 12345));
fb_cs_test(array(1 => 12345, "a" => 123124, "sdf" => 0.1234));
fb_cs_test(array(array("a")));
fb_cs_test(array(1, array("a")));
fb_cs_test(array(array("a"), 1));
fb_cs_test(array(array("a"), array(1)));
// Test skips
fb_cs_test(array(0 => "a", 1 => "b", 3 => "c"));
fb_cs_test(array(1 => "a", 2 => "b", 3 => "c"));
fb_cs_test(array(0 => "a", 2 => "b", 3 => "c"));
fb_cs_test(array(3 => "a"));
// Test for overflow (1ull << 63) - 1
fb_cs_test(array(9223372036854775807, 'a'));
// Test each power of two, +/- 1 and the negatives of them
// Test a single number and packed inside an array
for ($i = 0; $i < 64; ++$i) {
$n = 1 << $i;
fb_cs_test($n); fb_cs_test(array($n));
fb_cs_test($n-1); fb_cs_test(array($n-1));
fb_cs_test($n+1); fb_cs_test(array($n+1));
fb_cs_test(-$n); fb_cs_test(array(-$n));
fb_cs_test(-$n-1); fb_cs_test(array(-$n-1));
fb_cs_test(-$n+1); fb_cs_test(array(-$n+1));
}
echo "====\n";
// Test vector code (PHP can't create those, but they might come form
// C++ code in serialized strings)
$s = "\xfe\x01\x02\x03\xfc"; // VECTOR, 1, 2, 3, STOP
$ret = null;
var_dump(fb_compact_unserialize($s, $ret));
}
main();
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+9
Ver Arquivo
@@ -0,0 +1,9 @@
<?php
$ret = null;
var_dump(fb_thrift_unserialize(fb_thrift_serialize("test"), $ret));
var_dump($ret);
$ret = null;
var_dump(fb_thrift_unserialize(fb_thrift_serialize(array("test")), $ret));
var_dump($ret);
@@ -0,0 +1,7 @@
string(4) "test"
bool(true)
array(1) {
[0]=>
string(4) "test"
}
bool(true)
+35
Ver Arquivo
@@ -0,0 +1,35 @@
<?php
// See utf8ize.php
$INVALID_UTF_8_STRING = "\xe2\x82\x28";
// Falsey inputs
var_dump(fb_utf8_substr("", 0, 0));
var_dump(fb_utf8_substr("", 0, 1));
var_dump(fb_utf8_substr("hon\xE7k", 0, INT_MAX));
var_dump(fb_utf8_substr("hon\xE7k", 0, 3));
var_dump(fb_utf8_substr("hon\xE7k", -4, INT_MAX));
// Common cases
var_dump(fb_utf8_substr("X", 0, 1));
var_dump(fb_utf8_substr("Hello", 0, INT_MAX));
var_dump(fb_utf8_substr("Hello", 1, 2));
var_dump(fb_utf8_substr("Pr\u00DC\u00DDx", 2, 2));
// Negative start
var_dump(fb_utf8_substr("abcdef", -1, INT_MAX));
var_dump(fb_utf8_substr("abcdef", -2, INT_MAX));
var_dump(fb_utf8_substr("abcdef", -3, 1));
var_dump(fb_utf8_substr("", -1, 1));
var_dump(fb_utf8_substr("X", -1, 1));
var_dump(fb_utf8_substr("XY", -1, 1));
var_dump(fb_utf8_substr("Pr\u00DC\u00DDx", -3, 2));
// Negative lengths
var_dump(fb_utf8_substr("abcdef", 0, -1));
var_dump(fb_utf8_substr("abcdef", 2, -1));
var_dump(fb_utf8_substr("abcdef", 4, -4));
var_dump(fb_utf8_substr("abcdef", -3, -1));
// Invalid sequence
var_dump(fb_utf8_substr($INVALID_UTF_8_STRING, 0), "\uFFFD\x28");
+22
Ver Arquivo
@@ -0,0 +1,22 @@
bool(false)
bool(false)
bool(false)
string(3) "hon"
bool(false)
string(1) "X"
bool(false)
string(2) "el"
string(2) "\u"
bool(false)
bool(false)
string(1) "d"
bool(false)
string(1) "X"
string(1) "Y"
string(2) "DD"
string(5) "abcde"
string(3) "cde"
bool(false)
string(2) "de"
string(4) "("
string(7) "\uFFFD("
+63
Ver Arquivo
@@ -0,0 +1,63 @@
<?php
// This string includes an invalid UTF-8 sequence. The first byte
// suggests this is a three-byte UTF-8 sequence, but it's not valid.
//
// The legacy fb_utf8ize() implementation used to treat this three-byte
// sequence as two invalid code points followed by a valid ASCII character.
// It transforms the three bytes to the three code point sequence
// \xef\xbf\xbd\xef\xbf\xbd\x28.
//
// ICU treats this three-byte sequence as one invalid two-byte code point
// followed by a valid ASCII character. An ICU-based fb_utf8ize()
// implementation will transform the three bytes to the two code point
// sequence \xef\xbf\xbd\x28.
$INVALID_UTF_8_STRING = "\xe2\x82\x28";
$s = "hon\xE7k";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "test\xE0\xB0\xB1\xE0";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "test\xE0\xB0\xB1\xE0\xE0";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "\xfc";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "\xfc\xfc";
var_dump(fb_utf8ize($s));
var_dump($s);
// We intentionally consider null bytes invalid sequences.
$s = "abc\x00def";
var_dump(fb_utf8ize($s));
var_dump($s);
// ICU treats this as as two code points.
// The old implementation treated this as three code points.
$s = $INVALID_UTF_8_STRING;
var_dump(fb_utf8ize($s));
var_dump($s);
//// utf8_strlen
echo "====\n";
var_dump(fb_utf8_strlen(""));
var_dump(fb_utf8_strlen("a"));
var_dump(fb_utf8_strlen("ab"));
// Valid UTF-8 sequence returns code point count.
var_dump(fb_utf8_strlen("\ub098\ub294"));
var_dump(fb_utf8_strlen($INVALID_UTF_8_STRING));
$s = "abc\x00def";
var_dump(strlen($s));
var_dump(fb_utf8_strlen($s));
fb_utf8ize($s);
var_dump(strlen($s));
var_dump(fb_utf8_strlen($s));
+24
Ver Arquivo
@@ -0,0 +1,24 @@
bool(true)
string(7) "honk"
bool(true)
string(10) "testఱ"
bool(true)
string(13) "testఱ"
bool(true)
string(3) ""
bool(true)
string(6) ""
bool(true)
string(9) "abcdef"
bool(true)
string(4) "("
====
int(0)
int(1)
int(2)
int(12)
int(2)
int(7)
int(7)
int(9)
int(7)
+63
Ver Arquivo
@@ -0,0 +1,63 @@
<?php
// This string includes an invalid UTF-8 sequence. The first byte
// suggests this is a three-byte UTF-8 sequence, but it's not valid.
//
// The legacy fb_utf8ize() implementation used to treat this three-byte
// sequence as two invalid code points followed by a valid ASCII character.
// It transforms the three bytes to the three code point sequence
// \xef\xbf\xbd\xef\xbf\xbd\x28.
//
// ICU treats this three-byte sequence as one invalid two-byte code point
// followed by a valid ASCII character. An ICU-based fb_utf8ize()
// implementation will transform the three bytes to the two code point
// sequence \xef\xbf\xbd\x28.
$INVALID_UTF_8_STRING = "\xe2\x82\x28";
$s = "hon\xE7k";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "test\xE0\xB0\xB1\xE0";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "test\xE0\xB0\xB1\xE0\xE0";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "\xfc";
var_dump(fb_utf8ize($s));
var_dump($s);
$s = "\xfc\xfc";
var_dump(fb_utf8ize($s));
var_dump($s);
// We intentionally consider null bytes invalid sequences.
$s = "abc\x00def";
var_dump(fb_utf8ize($s));
var_dump($s);
// ICU treats this as as two code points.
// The old implementation treated this as three code points.
$s = $INVALID_UTF_8_STRING;
var_dump(fb_utf8ize($s));
var_dump($s);
//// utf8_strlen
echo "====\n";
var_dump(fb_utf8_strlen(""));
var_dump(fb_utf8_strlen("a"));
var_dump(fb_utf8_strlen("ab"));
// Valid UTF-8 sequence returns code point count.
var_dump(fb_utf8_strlen("\ub098\ub294"));
var_dump(fb_utf8_strlen($INVALID_UTF_8_STRING));
$s = "abc\x00def";
var_dump(strlen($s));
var_dump(fb_utf8_strlen($s));
fb_utf8ize($s);
var_dump(strlen($s));
var_dump(fb_utf8_strlen($s));
@@ -0,0 +1,24 @@
bool(true)
string(4) "honk"
bool(true)
string(7) "testఱ"
bool(true)
string(7) "testఱ"
bool(true)
string(0) ""
bool(true)
string(0) ""
bool(true)
string(6) "abcdef"
bool(true)
string(1) "("
====
int(0)
int(1)
int(2)
int(12)
int(2)
int(7)
int(7)
int(6)
int(6)
@@ -0,0 +1,2 @@
-vServer.Utf8izeReplace=0