Browse Source

This commit was manufactured by cvs2svn to create branch 'PHP_5_2'.

PECL_OPENSSL
SVN Migration 20 years ago
parent
commit
608baa409a
  1. 2
      ext/filter/CREDITS
  2. 68
      ext/filter/callback_filter.c
  3. 95
      ext/filter/config.m4
  4. 8
      ext/filter/config.w32
  5. 340
      ext/filter/sanitizing_filters.c
  6. 8
      ext/filter/tests/001.phpt
  7. 11
      ext/filter/tests/002.phpt
  8. 22
      ext/filter/tests/003.phpt
  9. 24
      ext/filter/tests/004.phpt
  10. 21
      ext/filter/tests/005.phpt
  11. 10
      ext/filter/tests/006.phpt
  12. 68
      ext/filter/tests/007.phpt
  13. 88
      ext/filter/tests/008.phpt
  14. 30
      ext/filter/tests/009.phpt
  15. 49
      ext/filter/tests/011.phpt
  16. 16
      ext/filter/tests/012.phpt
  17. 41
      ext/filter/tests/014.phpt
  18. 18
      ext/filter/tests/020.phpt
  19. 44
      ext/filter/tests/021.phpt
  20. 20
      ext/filter/tests/022.phpt
  21. 20
      ext/filter/tests/023.phpt
  22. 18
      ext/filter/tests/024.phpt
  23. 24
      ext/filter/tests/025.phpt
  24. 30
      ext/filter/tests/026.phpt
  25. 30
      ext/filter/tests/027.phpt
  26. 35
      ext/filter/tests/028.phpt
  27. 103
      ext/filter/tests/029.phpt
  28. 71
      ext/filter/tests/filter_data.phpt
  29. 757
      ext/json/JSON_parser.c
  30. 8
      ext/json/JSON_parser.h
  31. 76
      ext/json/README
  32. 88
      ext/json/config.m4
  33. 10
      ext/json/config.w32
  34. 449
      ext/json/json.c
  35. 135
      ext/json/json.dsp
  36. 152
      ext/json/package.xml
  37. 60
      ext/json/php_json.h
  38. 166
      ext/json/tests/fail001.phpt
  39. 895
      ext/json/tests/pass001.1.phpt
  40. 709
      ext/json/tests/pass001.phpt
  41. 276
      ext/json/tests/pass002.phpt
  42. 95
      ext/json/tests/pass003.phpt
  43. 179
      ext/json/utf8_decode.c
  44. 18
      ext/json/utf8_decode.h
  45. 56
      ext/json/utf8_to_utf16.c
  46. 3
      ext/json/utf8_to_utf16.h

2
ext/filter/CREDITS

@ -0,0 +1,2 @@
Input Filter
Rasmus Lerdorf, Derick Rethans

68
ext/filter/callback_filter.c

@ -0,0 +1,68 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+
| 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. |
+----------------------------------------------------------------------+
| Authors: Derick Rethans <derick@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include "php_filter.h"
void php_filter_callback(PHP_INPUT_FILTER_PARAM_DECL)
{
char *name = NULL;
zval *retval_ptr;
zval ***args;
int status;
if (!option_array || !zend_is_callable(option_array, IS_CALLABLE_CHECK_NO_ACCESS, &name)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument is expected to be a valid callback");
if (name) {
efree(name);
}
zval_dtor(value);
Z_TYPE_P(value) = IS_NULL;
return;
}
efree(name);
args = safe_emalloc(sizeof(zval **), 1, 0);
args[0] = &value;
status = call_user_function_ex(EG(function_table), NULL, option_array, &retval_ptr, 1, args, 0, NULL TSRMLS_CC);
if (status == SUCCESS && retval_ptr != NULL) {
zval_dtor(value);
*value = *retval_ptr;
zval_copy_ctor(value);
} else {
zval_dtor(value);
Z_TYPE_P(value) = IS_NULL;
}
if (retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
efree(args);
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

95
ext/filter/config.m4

@ -0,0 +1,95 @@
dnl $Id$
dnl config.m4 for input filtering extension
PHP_ARG_ENABLE(filter, whether to enable input filter support,
[ --disable-filter Disable input filter support], yes)
PHP_ARG_WITH(pcre-dir, pcre install prefix,
[ --with-pcre-dir FILTER: pcre install prefix], no, no)
if test "$PHP_FILTER" != "no"; then
dnl Check if configure is the PHP core configure
if test -n "$PHP_VERSION"; then
dnl This extension can not be build as shared when in PHP core
ext_shared=no
else
dnl This is PECL build, check if bundled PCRE library is used
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$INCLUDES
AC_EGREP_CPP(yes,[
#include <main/php_config.h>
#if defined(HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE)
yes
#endif
],[
PHP_PCRE_REGEX=yes
],[
AC_EGREP_CPP(yes,[
#include <main/php_config.h>
#if defined(HAVE_PCRE) && !defined(COMPILE_DL_PCRE)
yes
#endif
],[
PHP_PCRE_REGEX=pecl
],[
PHP_PCRE_REGEX=no
])
])
CPPFLAGS=$old_CPPFLAGS
fi
if test "$PHP_PCRE_REGEX" != "yes"; then
dnl
dnl If PCRE extension is enabled we can use the already found paths,
dnl otherwise we have to detect them here:
dnl
if test "$PHP_PCRE_REGEX" = "no" || test "$PHP_PCRE_REGEX" = "pecl"; then
dnl Set the PCRE search dirs correctly
case "$PHP_PCRE_DIR" in
yes|no)
PCRE_SEARCH_DIR="/usr/local /usr"
;;
*)
PCRE_SEARCH_DIR="$PHP_PCRE_DIR"
;;
esac
for i in $PCRE_SEARCH_DIR; do
if test -f $i/include/pcre/pcre.h; then
PCRE_INCDIR=$i/include/pcre
break
elif test -f $i/include/pcre.h; then
PCRE_INCDIR=$i/include
break
elif test -f $i/pcre.h; then
PCRE_INCDIR=$i
break
fi
done
if test -z "$PCRE_INCDIR"; then
AC_MSG_ERROR([Could not find pcre.h anywhere under $PCRE_SEARCH_DIR])
fi
for j in $PCRE_SEARCH_DIR/$PHP_LIBDIR $PCRE_SEARCH_DIR; do
if test -f $j/libpcre.a || test -f $j/libpcre.$SHLIB_SUFFIX_NAME; then
PCRE_LIBDIR=$j
break
fi
done
if test -z "$PCRE_LIBDIR" ; then
AC_MSG_ERROR([Could not find libpcre.(a|$SHLIB_SUFFIX_NAME) anywhere under $PCRE_SEARCH_DIR])
fi
fi
PHP_ADD_LIBRARY_WITH_PATH(pcre, $PCRE_LIBDIR, FILTER_SHARED_LIBADD)
PHP_ADD_INCLUDE($PCRE_INCDIR)
fi
PHP_NEW_EXTENSION(filter, filter.c sanitizing_filters.c logical_filters.c callback_filter.c, $ext_shared)
PHP_SUBST(FILTER_SHARED_LIBADD)
PHP_INSTALL_HEADERS([$ext_srcdir/php_filter.h])
fi

8
ext/filter/config.w32

@ -0,0 +1,8 @@
// $Id$
// vim:ft=javascript
ARG_ENABLE("filter", "Filter Support", "yes");
if (PHP_FILTER == "yes") {
EXTENSION("filter", "filter.c sanitizing_filters.c logical_filters.c callback_filter.c");
}

340
ext/filter/sanitizing_filters.c

@ -0,0 +1,340 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+
| 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. |
+----------------------------------------------------------------------+
| Authors: Derick Rethans <derick@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#include "php_filter.h"
#include "filter_private.h"
#include "ext/standard/php_smart_str.h"
/* {{{ STRUCTS */
typedef unsigned long filter_map[256];
/* }}} */
/* {{{ HELPER FUNCTIONS */
static void php_filter_encode_html(zval *value, char* chars, int encode_nul)
{
register int x, y;
smart_str str = {0};
int len = Z_STRLEN_P(value);
char *s = Z_STRVAL_P(value);
if (Z_STRLEN_P(value) == 0) {
return;
}
for (x = 0, y = 0; len--; x++, y++) {
if (strchr(chars, s[x]) || (encode_nul && s[x] == 0)) {
smart_str_appendl(&str, "&#", 2);
smart_str_append_long(&str, s[x]);
smart_str_appendc(&str, ';');
} else {
smart_str_appendc(&str, s[x]);
}
}
smart_str_0(&str);
efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = str.c;
Z_STRLEN_P(value) = str.len;
}
static void php_filter_encode_html_high_low(zval *value, long flags)
{
register int x, y;
smart_str str = {0};
int len = Z_STRLEN_P(value);
unsigned char *s = Z_STRVAL_P(value);
if (Z_STRLEN_P(value) == 0) {
return;
}
for (x = 0, y = 0; len--; x++, y++) {
if (((flags & FILTER_FLAG_ENCODE_LOW) && (s[x] < 32)) || ((flags & FILTER_FLAG_ENCODE_HIGH) && (s[x] > 127))) {
smart_str_appendl(&str, "&#", 2);
smart_str_append_long(&str, s[x]);
smart_str_appendc(&str, ';');
} else {
smart_str_appendc(&str, s[x]);
}
}
smart_str_0(&str);
efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = str.c;
Z_STRLEN_P(value) = str.len;
}
static unsigned char hexchars[] = "0123456789ABCDEF";
#define LOWALPHA "abcdefghijklmnopqrstuvwxyz"
#define HIALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define DIGIT "0123456789"
#define DEFAULT_URL_ENCODE LOWALPHA HIALPHA DIGIT "-._"
static void php_filter_encode_url(zval *value, char* chars, int high, int low, int encode_nul)
{
register int x, y;
unsigned char *str;
int len = Z_STRLEN_P(value);
char *s = Z_STRVAL_P(value);
str = (unsigned char *) safe_emalloc(3, len, 1);
for (x = 0, y = 0; len--; x++, y++) {
str[y] = (unsigned char) s[x];
if ((strlen(chars) && !strchr(chars, str[y])) || (high && str[y] > 127) || (low && str[y] < 32) || (encode_nul && str[y] == 0)) {
str[y++] = '%';
str[y++] = hexchars[(unsigned char) s[x] >> 4];
str[y] = hexchars[(unsigned char) s[x] & 15];
}
}
str[y] = '\0';
efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = str;
Z_STRLEN_P(value) = y;
}
static void php_filter_strip(zval *value, long flags)
{
unsigned char *buf, *str;
int i, c;
/* Optimization for if no strip flags are set */
if (! ((flags & FILTER_FLAG_STRIP_LOW) || (flags & FILTER_FLAG_STRIP_HIGH)) ) {
return;
}
str = Z_STRVAL_P(value);
buf = safe_emalloc(1, Z_STRLEN_P(value) + 1, 1);
c = 0;
for (i = 0; i < Z_STRLEN_P(value); i++) {
if ((str[i] > 127) && (flags & FILTER_FLAG_STRIP_HIGH)) {
} else if ((str[i] < 32) && (flags & FILTER_FLAG_STRIP_LOW)) {
} else {
buf[c] = str[i];
++c;
}
}
/* update zval string data */
buf[c] = '\0';
efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = buf;
Z_STRLEN_P(value) = c;
}
/* }}} */
/* {{{ FILTER MAP HELPERS */
static void filter_map_init(filter_map *map)
{
memset(map, 0, sizeof(filter_map));
}
static void filter_map_update(filter_map *map, int flag, unsigned char *allowed_list)
{
int l, i;
l = strlen(allowed_list);
for (i = 0; i < l; ++i) {
(*map)[allowed_list[i]] = flag;
}
}
static void filter_map_apply(zval *value, filter_map *map)
{
unsigned char *buf, *str;
int i, c;
str = Z_STRVAL_P(value);
buf = safe_emalloc(1, Z_STRLEN_P(value) + 1, 1);
c = 0;
for (i = 0; i < Z_STRLEN_P(value); i++) {
if ((*map)[str[i]]) {
buf[c] = str[i];
++c;
}
}
/* update zval string data */
buf[c] = '\0';
efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = buf;
Z_STRLEN_P(value) = c;
}
/* }}} */
/* {{{ php_filter_string */
void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL)
{
size_t new_len;
/* strip tags, implicitly also removes \0 chars */
new_len = php_strip_tags(Z_STRVAL_P(value), Z_STRLEN_P(value), NULL, NULL, 0);
Z_STRLEN_P(value) = new_len;
if (new_len == 0) {
zval_dtor(value);
ZVAL_EMPTY_STRING(value);
return;
}
if (! (flags & FILTER_FLAG_NO_ENCODE_QUOTES)) {
/* encode ' and " to numerical entity */
php_filter_encode_html(value, "'\"", 0);
}
/* strip high/strip low ( see flags )*/
php_filter_strip(value, flags);
/* encode low/encode high flags */
php_filter_encode_html_high_low(value, flags);
/* also all the flags - & encode as %xx */
if (flags & FILTER_FLAG_ENCODE_AMP) {
php_filter_encode_html(value, "&", 0);
}
}
/* }}} */
/* {{{ php_filter_encoded */
void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL)
{
/* apply strip_high and strip_low filters */
php_filter_strip(value, flags);
/* urlencode */
php_filter_encode_url(value, DEFAULT_URL_ENCODE, flags & FILTER_FLAG_ENCODE_HIGH, flags & FILTER_FLAG_ENCODE_LOW, 1);
}
/* }}} */
/* {{{ php_filter_special_chars */
void php_filter_special_chars(PHP_INPUT_FILTER_PARAM_DECL)
{
/* encodes ' " < > & \0 to numerical entities */
php_filter_encode_html(value, "'\"<>&", 1);
/* if strip low is not set, then we encode them as &#xx; */
php_filter_strip(value, flags);
php_filter_encode_html_high_low(value, FILTER_FLAG_ENCODE_LOW | flags);
}
/* }}} */
/* {{{ php_filter_unsafe_raw */
void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL)
{
/* Only if no flags are set (optimization) */
if (flags != 0 && Z_STRLEN_P(value) > 0) {
php_filter_strip(value, flags);
if (flags & FILTER_FLAG_ENCODE_AMP) {
php_filter_encode_html(value, "&", 0);
}
php_filter_encode_html_high_low(value, flags);
}
}
/* }}} */
/* {{{ php_filter_email */
#define SAFE "$-_.+"
#define EXTRA "!*'(),"
#define NATIONAL "{}|\\^~[]`"
#define PUNCTUATION "<>#%\""
#define RESERVED ";/?:@&="
void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL)
{
/* Check section 6 of rfc 822 http://www.faqs.org/rfcs/rfc822.html */
unsigned char *allowed_list = LOWALPHA HIALPHA DIGIT "!#$%&'*+-/=?^_`{|}~@.[]";
filter_map map;
filter_map_init(&map);
filter_map_update(&map, 1, allowed_list);
filter_map_apply(value, &map);
}
/* }}} */
/* {{{ php_filter_url */
void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL)
{
/* Strip all chars not part of section 5 of
* http://www.faqs.org/rfcs/rfc1738.html */
unsigned char *allowed_list = LOWALPHA HIALPHA DIGIT SAFE EXTRA NATIONAL PUNCTUATION RESERVED;
filter_map map;
filter_map_init(&map);
filter_map_update(&map, 1, allowed_list);
filter_map_apply(value, &map);
}
/* }}} */
/* {{{ php_filter_number_int */
void php_filter_number_int(PHP_INPUT_FILTER_PARAM_DECL)
{
/* strip everything [^0-9+-] */
unsigned char *allowed_list = "+-" DIGIT;
filter_map map;
filter_map_init(&map);
filter_map_update(&map, 1, allowed_list);
filter_map_apply(value, &map);
}
/* }}} */
/* {{{ php_filter_number_float */
void php_filter_number_float(PHP_INPUT_FILTER_PARAM_DECL)
{
/* strip everything [^0-9+-] */
unsigned char *allowed_list = "+-" DIGIT;
filter_map map;
filter_map_init(&map);
filter_map_update(&map, 1, allowed_list);
/* depending on flags, strip '.', 'e', ",", "'" */
if (flags & FILTER_FLAG_ALLOW_FRACTION) {
filter_map_update(&map, 2, ".");
}
if (flags & FILTER_FLAG_ALLOW_THOUSAND) {
filter_map_update(&map, 3, ",");
}
if (flags & FILTER_FLAG_ALLOW_SCIENTIFIC) {
filter_map_update(&map, 4, "eE");
}
filter_map_apply(value, &map);
}
/* }}} */
/* {{{ php_filter_magic_quotes */
void php_filter_magic_quotes(PHP_INPUT_FILTER_PARAM_DECL)
{
char *buf;
int len;
/* just call php_addslashes quotes */
buf = php_addslashes(Z_STRVAL_P(value), Z_STRLEN_P(value), &len, 0 TSRMLS_CC);
efree(Z_STRVAL_P(value));
Z_STRVAL_P(value) = buf;
Z_STRLEN_P(value) = len;
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

8
ext/filter/tests/001.phpt

@ -0,0 +1,8 @@
--TEST--
Simple GET test
--GET--
a=1
--FILE--
<?php echo $_GET['a']; ?>
--EXPECT--
1

11
ext/filter/tests/002.phpt

@ -0,0 +1,11 @@
--TEST--
GET test with 2 values and an empty one
--GET--
a=1&b=&c=3
--FILE--
<?php echo $_GET['a'];
echo $_GET['b'];
echo $_GET['c'];
?>
--EXPECT--
13

22
ext/filter/tests/003.phpt

@ -0,0 +1,22 @@
--TEST--
GET/POST/REQUEST Test
--POST--
d=4&e=5
--GET--
a=1&b=&c=3
--FILE--
<?php echo $_GET['a'];
echo $_GET['b'];
echo $_GET['c'];
echo $_POST['d'];
echo $_POST['e'];
echo "\n";
echo $_REQUEST['a'];
echo $_REQUEST['b'];
echo $_REQUEST['c'];
echo $_REQUEST['d'];
echo $_REQUEST['e'];
?>
--EXPECT--
1345
1345

24
ext/filter/tests/004.phpt

@ -0,0 +1,24 @@
--TEST--
GET/POST/REQUEST Test with filtered data
--INI--
filter.default=special_chars
--POST--
d="quotes"&e=\slash
--GET--
a=O'Henry&b=&c=<b>Bold</b>
--FILE--
<?php echo $_GET['a'];
echo $_GET['b'];
echo $_GET['c'];
echo $_POST['d'];
echo $_POST['e'];
echo "\n";
echo $_REQUEST['a'];
echo $_REQUEST['b'];
echo $_REQUEST['c'];
echo $_REQUEST['d'];
echo $_REQUEST['e'];
?>
--EXPECT--
O&#39;HenryBold&quot;quotes&quot;\slash
O&#39;HenryBold&quot;quotes&quot;\slash

21
ext/filter/tests/005.phpt

@ -0,0 +1,21 @@
--TEST--
GET/REQUEST Test with fifa example data
--INI--
filter.default=stripped
--GET--
id=f03_photos&pgurl=http%3A//fifaworldcup.yahoo.com/03/en/photozone/index.html
--FILE--
<?php
echo $_GET['id'];
echo "\n";
echo $_GET['pgurl'];
echo "\n";
echo $_REQUEST['id'];
echo "\n";
echo $_REQUEST['pgurl'];
?>
--EXPECT--
f03_photos
http://fifaworldcup.yahoo.com/03/en/photozone/index.html
f03_photos
http://fifaworldcup.yahoo.com/03/en/photozone/index.html

10
ext/filter/tests/006.phpt

@ -0,0 +1,10 @@
--TEST--
filter() test
--POST--
foo=<b>abc</b>
--FILE--
<?php
echo input_get(INPUT_POST, 'foo', FILTER_SANITIZE_STRIPPED);
?>
--EXPECT--
abc

68
ext/filter/tests/007.phpt

@ -0,0 +1,68 @@
--TEST--
input_has_variable()
--GET--
a=qwe&abc=<a>href</a>
--POST--
b=qwe&bbc=<a>href</a>
--FILE--
<?php
var_dump(input_has_variable(INPUT_GET, "a"));
var_dump(input_has_variable(INPUT_GET, "abc"));
var_dump(input_has_variable(INPUT_GET, "nonex"));
var_dump(input_has_variable(INPUT_GET, " "));
var_dump(input_has_variable(INPUT_GET, ""));
var_dump(input_has_variable(INPUT_GET, array()));
var_dump(input_has_variable(INPUT_POST, "b"));
var_dump(input_has_variable(INPUT_POST, "bbc"));
var_dump(input_has_variable(INPUT_POST, "nonex"));
var_dump(input_has_variable(INPUT_POST, " "));
var_dump(input_has_variable(INPUT_POST, ""));
var_dump(input_has_variable(INPUT_POST, array()));
var_dump(input_has_variable(-1, ""));
var_dump(input_has_variable("", ""));
var_dump(input_has_variable(array(), array()));
var_dump(input_has_variable(array(), ""));
var_dump(input_has_variable("", array()));
echo "Done\n";
?>
--EXPECTF--
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)
PHP Warning: input_has_variable() expects parameter 2 to be string, array given in %s on line %d
Warning: input_has_variable() expects parameter 2 to be string, array given in %s on line %d
NULL
bool(true)
bool(true)
bool(false)
bool(false)
bool(false)
PHP Warning: input_has_variable() expects parameter 2 to be string, array given in %s on line %d
Warning: input_has_variable() expects parameter 2 to be string, array given in %s on line %d
NULL
bool(false)
PHP Warning: input_has_variable() expects parameter 1 to be long, string given in %s on line %d
Warning: input_has_variable() expects parameter 1 to be long, string given in %s on line %d
NULL
PHP Warning: input_has_variable() expects parameter 1 to be long, array given in %s on line %d
Warning: input_has_variable() expects parameter 1 to be long, array given in %s on line %d
NULL
PHP Warning: input_has_variable() expects parameter 1 to be long, array given in %s on line %d
Warning: input_has_variable() expects parameter 1 to be long, array given in %s on line %d
NULL
PHP Warning: input_has_variable() expects parameter 1 to be long, string given in %s on line %d
Warning: input_has_variable() expects parameter 1 to be long, string given in %s on line %d
NULL
Done

88
ext/filter/tests/008.phpt

@ -0,0 +1,88 @@
--TEST--
input_filters_list()
--FILE--
<?php
var_dump(input_filters_list());
var_dump(input_filters_list(array()));
echo "Done\n";
?>
--EXPECTF--
array(18) {
[0]=>
string(3) "int"
[1]=>
string(7) "boolean"
[2]=>
string(5) "float"
[3]=>
string(15) "validate_regexp"
[4]=>
string(12) "validate_url"
[5]=>
string(14) "validate_email"
[6]=>
string(11) "validate_ip"
[7]=>
string(6) "string"
[8]=>
string(8) "stripped"
[9]=>
string(7) "encoded"
[10]=>
string(13) "special_chars"
[11]=>
string(10) "unsafe_raw"
[12]=>
string(5) "email"
[13]=>
string(3) "url"
[14]=>
string(10) "number_int"
[15]=>
string(12) "number_float"
[16]=>
string(12) "magic_quotes"
[17]=>
string(8) "callback"
}
array(18) {
[0]=>
string(3) "int"
[1]=>
string(7) "boolean"
[2]=>
string(5) "float"
[3]=>
string(15) "validate_regexp"
[4]=>
string(12) "validate_url"
[5]=>
string(14) "validate_email"
[6]=>
string(11) "validate_ip"
[7]=>
string(6) "string"
[8]=>
string(8) "stripped"
[9]=>
string(7) "encoded"
[10]=>
string(13) "special_chars"
[11]=>
string(10) "unsafe_raw"
[12]=>
string(5) "email"
[13]=>
string(3) "url"
[14]=>
string(10) "number_int"
[15]=>
string(12) "number_float"
[16]=>
string(12) "magic_quotes"
[17]=>
string(8) "callback"
}
Done

30
ext/filter/tests/009.phpt

@ -0,0 +1,30 @@
--TEST--
input_name_to_filter()
--FILE--
<?php
var_dump(input_name_to_filter("stripped"));
var_dump(input_name_to_filter("string"));
var_dump(input_name_to_filter("url"));
var_dump(input_name_to_filter("int"));
var_dump(input_name_to_filter("none"));
var_dump(input_name_to_filter(array()));
var_dump(input_name_to_filter(-1));
var_dump(input_name_to_filter(0,0,0));
echo "Done\n";
?>
--EXPECTF--
int(513)
int(513)
int(518)
int(257)
NULL
Warning: input_name_to_filter() expects parameter 1 to be string, array given in %s on line %d
NULL
NULL
Warning: input_name_to_filter() expects exactly 1 parameter, 3 given in %s on line %d
NULL
Done

49
ext/filter/tests/011.phpt

@ -0,0 +1,49 @@
--TEST--
input_get()
--GET--
a=<b>test</b>&b=http://example.com
--POST--
c=<p>string</p>&d=12345.7
--FILE--
<?php
var_dump(input_get(INPUT_GET, "a", FILTER_SANITIZE_STRIPPED));
var_dump(input_get(INPUT_GET, "b", FILTER_SANITIZE_URL));
var_dump(input_get(INPUT_GET, "a", FILTER_SANITIZE_SPECIAL_CHARS, array(1,2,3,4,5)));
var_dump(input_get(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass));
var_dump(input_get(INPUT_POST, "c", FILTER_SANITIZE_STRIPPED, array(5,6,7,8)));
var_dump(input_get(INPUT_POST, "d", FILTER_VALIDATE_FLOAT));
var_dump(input_get(INPUT_POST, "c", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(input_get(INPUT_POST, "d", FILTER_VALIDATE_INT));
var_dump(input_get(new stdClass, "d"));
var_dump(input_get(INPUT_POST, "c", "", ""));
var_dump(input_get("", "", "", "", ""));
var_dump(input_get(0, 0, 0, 0, 0));
echo "Done\n";
?>
--EXPECTF--
string(4) "test"
string(18) "http://example.com"
string(27) "&#60;b&#62;test&#60;/b&#62;"
NULL
string(6) "string"
float(12345.7)
string(29) "&#60;p&#62;string&#60;/p&#62;"
NULL
PHP Warning: input_get() expects parameter 1 to be long, object given in %s on line %d
Warning: input_get() expects parameter 1 to be long, object given in %s on line %d
NULL
PHP Warning: input_get() expects parameter 3 to be long, string given in %s on line %d
Warning: input_get() expects parameter 3 to be long, string given in %s on line %d
NULL
PHP Warning: input_get() expects parameter 1 to be long, string given in %s on line %d
Warning: input_get() expects parameter 1 to be long, string given in %s on line %d
NULL
bool(false)
Done

16
ext/filter/tests/012.phpt

@ -0,0 +1,16 @@
--TEST--
input_get()
--FILE--
<?php
var_dump(input_get(INPUT_GET, "test"));
var_dump(input_get(INPUT_POST, "test"));
var_dump(input_get(INPUT_COOKIE, ""));
echo "Done\n";
?>
--EXPECT--
bool(false)
bool(false)
bool(false)
Done

41
ext/filter/tests/014.phpt

@ -0,0 +1,41 @@
--TEST--
filter_data() and FILTER_VALIDATE_BOOLEAN
--FILE--
<?php
var_dump(filter_data("no", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data(new stdClass, FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("yes", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("true", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("false", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("off", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("on", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("0", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("1", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("NONE", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data(-1, FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("000000", FILTER_VALIDATE_BOOLEAN));
var_dump(filter_data("111111", FILTER_VALIDATE_BOOLEAN));
echo "Done\n";
?>
--EXPECTF--
bool(false)
Notice: Object of class stdClass to string conversion in %s on line %d
NULL
bool(true)
bool(true)
bool(false)
bool(false)
bool(true)
bool(false)
bool(true)
NULL
bool(false)
NULL
NULL
NULL
Done

18
ext/filter/tests/020.phpt

@ -0,0 +1,18 @@
--TEST--
filter_data() and FILTER_SANITIZE_MAGIC_QUOTES
--FILE--
<?php
var_dump(filter_data("test'asd'asd'' asd\'\"asdfasdf", FILTER_SANITIZE_MAGIC_QUOTES));
var_dump(filter_data("'", FILTER_SANITIZE_MAGIC_QUOTES));
var_dump(filter_data("", FILTER_SANITIZE_MAGIC_QUOTES));
var_dump(filter_data(-1, FILTER_SANITIZE_MAGIC_QUOTES));
echo "Done\n";
?>
--EXPECT--
string(36) "test\'asd\'asd\'\' asd\\\'\"asdfasdf"
string(2) "\'"
string(0) ""
string(2) "-1"
Done

44
ext/filter/tests/021.phpt

@ -0,0 +1,44 @@
--TEST--
filter_data() and FILTER_SANITIZE_NUMBER_*
--FILE--
<?php
var_dump(filter_data("qwertyu123456dfghj", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("asd123123.asd123.23", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("123,23", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("0", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("asd123.2asd", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("qwertyuiop", FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_data("123.4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_data("123,4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_data("123.4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
var_dump(filter_data("123,4", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
var_dump(filter_data("123.4e", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC));
var_dump(filter_data("123,4E", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_SCIENTIFIC));
var_dump(filter_data("qwe123,4qwe", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_data("werty65456.34", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_data("234.56fsfd", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
var_dump(filter_data("", FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
echo "Done\n";
?>
--EXPECT--
string(6) "123456"
string(11) "12312312323"
string(5) "12323"
string(0) ""
string(1) "0"
string(4) "1232"
string(0) ""
string(5) "123.4"
string(4) "1234"
string(4) "1234"
string(5) "123,4"
string(5) "1234e"
string(5) "1234E"
string(4) "1234"
string(8) "65456.34"
string(6) "234.56"
string(0) ""
Done

20
ext/filter/tests/022.phpt

@ -0,0 +1,20 @@
--TEST--
filter_data() and FILTER_SANITIZE_EMAIL
--FILE--
<?php
var_dump(filter_data("a@b.c", FILTER_SANITIZE_EMAIL));
var_dump(filter_data("a[!@#$%^&*()@a@#$%^&*(.com@#$%^&*(", FILTER_SANITIZE_EMAIL));
var_dump(filter_data("white space here \ \ \" som more", FILTER_SANITIZE_EMAIL));
var_dump(filter_data("", FILTER_SANITIZE_EMAIL));
var_dump(filter_data("123456789000000", FILTER_SANITIZE_EMAIL));
echo "Done\n";
?>
--EXPECTF--
string(5) "a@b.c"
string(30) "a[!@#$%^&*@a@#$%^&*.com@#$%^&*"
string(21) "whitespaceheresommore"
string(0) ""
string(15) "123456789000000"
Done

20
ext/filter/tests/023.phpt

@ -0,0 +1,20 @@
--TEST--
filter_data() and FILTER_UNSAFE_RAW
--FILE--
<?php
var_dump(filter_data("}\"<p>test para</p>", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_data("a[!@#<b>$%^&*()@a@#$%^&*(.<br>com@#$%^&*(", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_data("white space here \ \ \" some more", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_data("", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_data(" 123456789000000 <qwertyuiop> ", FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_AMP));
echo "Done\n";
?>
--EXPECT--
string(18) "}"<p>test para</p>"
string(53) "a[!@#<b>$%^&#38;*()@a@#$%^&#38;*(.<br>com@#$%^&#38;*("
string(32) "white space here \ \ " some more"
string(0) ""
string(48) " 123456789000000 <qwertyuiop> "
Done

18
ext/filter/tests/024.phpt

@ -0,0 +1,18 @@
--TEST--
filter_data() and FILTER_SANITIZE_ENCODED
--FILE--
<?php
var_dump(filter_data("\"<br>blah</ph>", FILTER_SANITIZE_ENCODED));
var_dump(filter_data("", FILTER_SANITIZE_ENCODED));
var_dump(filter_data(" text here ", FILTER_SANITIZE_ENCODED));
var_dump(filter_data("!@#$%^&*()QWERTYUIOP{ASDFGHJKL:\"ZXCVBNM<>?", FILTER_SANITIZE_ENCODED));
echo "Done\n";
?>
--EXPECT--
string(26) "%22%3Cbr%3Eblah%3C%2Fph%3E"
string(0) ""
string(23) "%20%20text%20here%20%20"
string(74) "%21%40%23%24%25%5E%26%2A%28%29QWERTYUIOP%7BASDFGHJKL%3A%22ZXCVBNM%3C%3E%3F"
Done

24
ext/filter/tests/025.phpt

@ -0,0 +1,24 @@
--TEST--
filter_data() and FILTER_SANITIZE_STRING
--FILE--
<?php
var_dump(filter_data("", FILTER_SANITIZE_STRING));
var_dump(filter_data("<>", FILTER_SANITIZE_STRING));
var_dump(filter_data("<>!@#$%^&*()'\"", FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES));
var_dump(filter_data("<>!@#$%^&*()'\"", FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_AMP));
var_dump(filter_data("<>`1234567890", FILTER_SANITIZE_STRING));
var_dump(filter_data("`123`", FILTER_SANITIZE_STRING));
var_dump(filter_data(".", FILTER_SANITIZE_STRING));
echo "Done\n";
?>
--EXPECT--
string(0) ""
string(0) ""
string(12) "!@#$%^&*()'""
string(32) "!@#$%^&#38;*()&#38;#39;&#38;#34;"
string(11) "`1234567890"
string(5) "`123`"
string(1) "."
Done

30
ext/filter/tests/026.phpt

@ -0,0 +1,30 @@
--TEST--
filter_data() and FILTER_SANITIZE_STRIPPED
--FILE--
<?php
var_dump(filter_data("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED));
var_dump(filter_data("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED));
var_dump(filter_data("", FILTER_SANITIZE_STRIPPED));
var_dump(filter_data("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW));
var_dump(filter_data("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW));
var_dump(filter_data("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_LOW));
var_dump(filter_data("<p>Let me <font color=\"#000000\">see</font> you <br /><b>Stripped</b> down to the bone</p>", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH));
var_dump(filter_data("!@#$%^&*()><<>+_\"'<br><p /><li />", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH));
var_dump(filter_data("", FILTER_SANITIZE_STRIPPED, FILTER_FLAG_STRIP_HIGH));
echo "Done\n";
?>
--EXPECTF--
string(40) "Let me see you Stripped down to the bone"
string(11) "!@#$%^&*()>"
string(0) ""
string(40) "Let me see you Stripped down to the bone"
string(11) "!@#$%^&*()>"
string(0) ""
string(40) "Let me see you Stripped down to the bone"
string(11) "!@#$%^&*()>"
string(0) ""
Done

30
ext/filter/tests/027.phpt

@ -0,0 +1,30 @@
--TEST--
filter_data() and FILTER_SANITIZE_ENCODED
--FILE--
<?php
var_dump(filter_data("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED));
var_dump(filter_data("<data&sons>", FILTER_SANITIZE_ENCODED));
var_dump(filter_data("", FILTER_SANITIZE_ENCODED));
var_dump(filter_data("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_data("<data&sons>", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_data("", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_data("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_data("<data&sons>", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_data("", FILTER_SANITIZE_ENCODED, FILTER_FLAG_ENCODE_HIGH));
echo "Done\n";
?>
--EXPECT--
string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn"
string(17) "%3Cdata%26sons%3E"
string(0) ""
string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn"
string(17) "%3Cdata%26sons%3E"
string(0) ""
string(75) "%3F%3E%3C%21%40%23%24%25%5E%26%2A%28%29%7D%7B%7EQwertyuilfdsasdfgmnbvcxcvbn"
string(17) "%3Cdata%26sons%3E"
string(0) ""
Done

35
ext/filter/tests/028.phpt

@ -0,0 +1,35 @@
--TEST--
filter_data() and FILTER_SANITIZE_SPECIAL_CHARS
--FILE--
<?php
var_dump(filter_data("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(filter_data("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(filter_data("", FILTER_SANITIZE_SPECIAL_CHARS));
var_dump(filter_data("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_data("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_data("", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));
var_dump(filter_data("?><!@#$%^&*()}{~Qwertyuilfdsasdfgmnbvcxcvbn", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_data("<data&sons>", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_data("", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_data("кириллица", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_HIGH));
var_dump(filter_data("кириллица", FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_ENCODE_LOW));
echo "Done\n";
?>
--EXPECT--
string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
string(23) "&#60;data&#38;sons&#62;"
string(0) ""
string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
string(23) "&#60;data&#38;sons&#62;"
string(0) ""
string(55) "?&#62;&#60;!@#$%^&#38;*()}{~Qwertyuilfdsasdfgmnbvcxcvbn"
string(23) "&#60;data&#38;sons&#62;"
string(0) ""
string(108) "&#208;&#186;&#208;&#184;&#209;&#128;&#208;&#184;&#208;&#187;&#208;&#187;&#208;&#184;&#209;&#134;&#208;&#176;"
string(18) "кириллица"
Done

103
ext/filter/tests/029.phpt

@ -0,0 +1,103 @@
--TEST--
filter_data() and FILTER_CALLBACK
--FILE--
<?php
/* Simple callback function */
function test($var) {
return strtoupper($var);
}
var_dump(filter_data("data", FILTER_CALLBACK, "test"));
var_dump(filter_data("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, "test"));
var_dump(filter_data("", FILTER_CALLBACK, "test"));
var_dump(filter_data("qwe", FILTER_CALLBACK, "no such func"));
var_dump(filter_data("qwe", FILTER_CALLBACK, ""));
var_dump(filter_data("qwe", FILTER_CALLBACK));
/* Simple class method callback */
class test_class {
static function test ($var) {
return strtolower($var);
}
}
var_dump(filter_data("dAtA", FILTER_CALLBACK, array("test_class", "test")));
var_dump(filter_data("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, array("test_class","test")));
var_dump(filter_data("", FILTER_CALLBACK, array("test_class","test")));
/* empty function without return value */
function test1($var) {
}
var_dump(filter_data("data", FILTER_CALLBACK, "test1"));
var_dump(filter_data("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, "test1"));
var_dump(filter_data("", FILTER_CALLBACK, "test1"));
/* attempting to change data by reference */
function test2(&$var) {
$var = 1;
}
var_dump(filter_data("data", FILTER_CALLBACK, "test2"));
var_dump(filter_data("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, "test2"));
var_dump(filter_data("", FILTER_CALLBACK, "test2"));
/* unsetting data */
function test3(&$var) {
unset($var);
}
var_dump(filter_data("data", FILTER_CALLBACK, "test3"));
var_dump(filter_data("~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?\"}{:", FILTER_CALLBACK, "test3"));
var_dump(filter_data("", FILTER_CALLBACK, "test3"));
/* unset data and return value */
function test4(&$var) {
unset($var);
return 1;
}
var_dump(filter_data("data", FILTER_CALLBACK, "test4"));
/* thrown exception in the callback */
function test5(&$var) {
throw new Exception("test");
}
try {
var_dump(filter_data("data", FILTER_CALLBACK, "test5"));
} catch (Exception $e) {
var_dump($e->getMessage());
}
echo "Done\n";
?>
--EXPECTF--
string(4) "DATA"
string(46) "~!@#$%^&*()_QWERTYUIOPASDFGHJKLZXCVBNM<>>?"}{:"
string(0) ""
Warning: filter_data(): First argument is expected to be a valid callback in %s on line %d
NULL
Warning: filter_data(): First argument is expected to be a valid callback in %s on line %d
NULL
Warning: filter_data(): First argument is expected to be a valid callback in %s on line %d
NULL
string(4) "data"
string(46) "~!@#$%^&*()_qwertyuiopasdfghjklzxcvbnm<>>?"}{:"
string(0) ""
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
int(1)
string(4) "test"
Done

71
ext/filter/tests/filter_data.phpt

@ -0,0 +1,71 @@
--TEST--
Simple filter_data() tests
--FILE--
<?php
/* Integer */
$data = "-123"; var_dump(filter_data($data, FILTER_VALIDATE_INT));
$data = "0"; var_dump(filter_data($data, FILTER_VALIDATE_INT));
$data = "123"; var_dump(filter_data($data, FILTER_VALIDATE_INT));
$data = -123; var_dump(filter_data($data, FILTER_VALIDATE_INT));
$data = 0; var_dump(filter_data($data, FILTER_VALIDATE_INT));
$data = 123; var_dump(filter_data($data, FILTER_VALIDATE_INT));
$data = ""; var_dump(filter_data($data, FILTER_VALIDATE_INT));
echo "\n";
/* Float */
$data = "-0.123"; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
$data = "0.00"; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
$data = "1.23"; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
$data = -1.23; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
$data = 0.0; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
$data = 1.23; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
$data = ""; var_dump(filter_data($data, FILTER_VALIDATE_FLOAT));
echo "\n";
/* Boolean */
$data = "on"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "off"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "yes"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "no"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "true"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "false"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "1"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = "0"; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = 1; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = 0; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = true; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = false; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
$data = ""; var_dump(filter_data($data, FILTER_VALIDATE_BOOLEAN));
?>
--EXPECT--
int(-123)
int(0)
int(123)
int(-123)
int(0)
int(123)
int(0)
float(-0.123)
float(0)
float(1.23)
float(-1.23)
float(0)
float(1.23)
float(0)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(false)

757
ext/json/JSON_parser.c

@ -0,0 +1,757 @@
/* JSON_parser.c */
/* 2005-12-30 */
/*
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "JSON_parser.h"
#include <stdio.h>
#define true 1
#define false 0
/*
Characters are mapped into these 32 symbol classes. This allows for
significant reductions in the size of the state transition table.
*/
/* error */
#define S_ERR -1
/* space */
#define S_SPA 0
/* other whitespace */
#define S_WSP 1
/* { */
#define S_LBE 2
/* } */
#define S_RBE 3
/* [ */
#define S_LBT 4
/* ] */
#define S_RBT 5
/* : */
#define S_COL 6
/* , */
#define S_COM 7
/* " */
#define S_QUO 8
/* \ */
#define S_BAC 9
/* / */
#define S_SLA 10
/* + */
#define S_PLU 11
/* - */
#define S_MIN 12
/* . */
#define S_DOT 13
/* 0 */
#define S_ZER 14
/* 123456789 */
#define S_DIG 15
/* a */
#define S__A_ 16
/* b */
#define S__B_ 17
/* c */
#define S__C_ 18
/* d */
#define S__D_ 19
/* e */
#define S__E_ 20
/* f */
#define S__F_ 21
/* l */
#define S__L_ 22
/* n */
#define S__N_ 23
/* r */
#define S__R_ 24
/* s */
#define S__S_ 25
/* t */
#define S__T_ 26
/* u */
#define S__U_ 27
/* ABCDF */
#define S_A_F 28
/* E */
#define S_E 29
/* everything else */
#define S_ETC 30
/*
This table maps the 128 ASCII characters into the 32 character classes.
The remaining Unicode characters should be mapped to S_ETC.
*/
static int ascii_class[128] = {
S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
S_ERR, S_WSP, S_WSP, S_ERR, S_ERR, S_WSP, S_ERR, S_ERR,
S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR,
S_SPA, S_ETC, S_QUO, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
S_ETC, S_ETC, S_ETC, S_PLU, S_COM, S_MIN, S_DOT, S_SLA,
S_ZER, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG,
S_DIG, S_DIG, S_COL, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
S_ETC, S_A_F, S_A_F, S_A_F, S_A_F, S_E , S_A_F, S_ETC,
S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC,
S_ETC, S_ETC, S_ETC, S_LBT, S_BAC, S_RBT, S_ETC, S_ETC,
S_ETC, S__A_, S__B_, S__C_, S__D_, S__E_, S__F_, S_ETC,
S_ETC, S_ETC, S_ETC, S_ETC, S__L_, S_ETC, S__N_, S_ETC,
S_ETC, S_ETC, S__R_, S__S_, S__T_, S__U_, S_ETC, S_ETC,
S_ETC, S_ETC, S_ETC, S_LBE, S_ETC, S_RBE, S_ETC, S_ETC
};
/*
The state transition table takes the current state and the current symbol,
and returns either a new state or an action. A new state is a number between
0 and 29. An action is a negative number between -1 and -9. A JSON text is
accepted if the end of the text is in state 9 and mode is MODE_DONE.
*/
static int state_transition_table[30][31] = {
/* 0*/ { 0, 0,-8,-1,-6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/* 1*/ { 1, 1,-1,-9,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/* 2*/ { 2, 2,-8,-1,-6,-5,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1},
/* 3*/ { 3,-1, 3, 3, 3, 3, 3, 3,-4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
/* 4*/ {-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1, 3,-1, 3, 3,-1, 3, 5,-1,-1,-1},
/* 5*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 6, 6, 6, 6, 6, 6, 6, 6,-1,-1,-1,-1,-1,-1, 6, 6,-1},
/* 6*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 7, 7, 7, 7, 7, 7, 7, 7,-1,-1,-1,-1,-1,-1, 7, 7,-1},
/* 7*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 8, 8, 8, 8, 8, 8, 8, 8,-1,-1,-1,-1,-1,-1, 8, 8,-1},
/* 8*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3, 3,-1},
/* 9*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*10*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1},
/*11*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1},
/*12*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*13*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*14*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,-1,-1,-1,-1,-1,-1,-1,-1},
/*15*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,-1,-1},
/*16*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*17*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,18,-1,-1,-1},
/*18*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,-1,-1,-1,-1,-1,-1,-1,-1},
/*19*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1},
/*20*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*21*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*22*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,22,22,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1},
/*23*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,23,23,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1},
/*24*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,25,25,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*25*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*26*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*27*/ {27,27,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
/*28*/ {28,28,-8,-1,-6,-1,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1},
/*29*/ {29,29,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}
};
#define JSON_PARSER_MAX_DEPTH 20
/*
A stack maintains the states of nested structures.
*/
typedef struct json_parser
{
int the_stack[JSON_PARSER_MAX_DEPTH];
zval *the_zstack[JSON_PARSER_MAX_DEPTH];
int the_top;
} json_parser;
/*
These modes can be pushed on the PDA stack.
*/
#define MODE_DONE 1
#define MODE_KEY 2
#define MODE_OBJECT 3
#define MODE_ARRAY 4
/*
Push a mode onto the stack. Return false if there is overflow.
*/
static int
push(json_parser *json, zval *z, int mode)
{
json->the_top += 1;
if (json->the_top >= JSON_PARSER_MAX_DEPTH) {
return false;
}
json->the_stack[json->the_top] = mode;
return true;
}
/*
Pop the stack, assuring that the current mode matches the expectation.
Return false if there is underflow or if the modes mismatch.
*/
static int
pop(json_parser *json, zval *z, int mode)
{
if (json->the_top < 0 || json->the_stack[json->the_top] != mode) {
return false;
}
json->the_stack[json->the_top] = 0;
json->the_top -= 1;
return true;
}
static int dehexchar(char c)
{
if (c >= '0' && c <= '9')
{
return c - '0';
}
else if (c >= 'A' && c <= 'F')
{
return c - ('A' - 10);
}
else if (c >= 'a' && c <= 'f')
{
return c - ('a' - 10);
}
else
{
return -1;
}
}
static void json_create_zval(zval **z, smart_str *buf, int type)
{
ALLOC_INIT_ZVAL(*z);
if (type == IS_LONG)
{
ZVAL_LONG(*z, atol(buf->c));
}
else if (type == IS_DOUBLE)
{
ZVAL_DOUBLE(*z, atof(buf->c));
}
else if (type == IS_STRING)
{
ZVAL_STRINGL(*z, buf->c, buf->len, 1);
}
else if (type == IS_BOOL)
{
ZVAL_BOOL(*z, (*(buf->c) == 't'));
}
else /* type == IS_NULL) || type unknown */
{
ZVAL_NULL(*z);
}
}
static void utf16_to_utf8(smart_str *buf, unsigned short utf16)
{
if (utf16 < 0x80)
{
smart_str_appendc(buf, (unsigned char) utf16);
}
else if (utf16 < 0x800)
{
smart_str_appendc(buf, 0xc0 | (utf16 >> 6));
smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
}
else
{
smart_str_appendc(buf, 0xe0 | (utf16 >> 12));
smart_str_appendc(buf, 0x80 | ((utf16 >> 6) & 0x3f));
smart_str_appendc(buf, 0x80 | (utf16 & 0x3f));
}
}
static void attach_zval(json_parser *json, int up, int cur, smart_str *key, int assoc TSRMLS_DC)
{
zval *root = json->the_zstack[up];
zval *child = json->the_zstack[cur];
int up_mode = json->the_stack[up];
if (up_mode == MODE_ARRAY)
{
add_next_index_zval(root, child);
}
else if (up_mode == MODE_OBJECT)
{
if (!assoc)
{
add_property_zval(root, key->c, child);
#if PHP_MAJOR_VERSION >= 5
ZVAL_DELREF(child);
#endif
}
else
{
add_assoc_zval(root, key->c, child);
}
key->len = 0;
}
}
#define FREE_BUFFERS() do { smart_str_free(&buf); smart_str_free(&key); } while (0);
#define SWAP_BUFFERS(from, to) do { \
char *t1 = from.c; \
int t2 = from.a; \
from.c = to.c; \
from.a = to.a; \
to.c = t1; \
to.a = t2; \
to.len = from.len; \
from.len = 0; \
} while(0);
#define JSON_RESET_TYPE() do { type = -1; } while(0);
#define JSON(x) the_json.x
/*
The JSON_parser takes a UTF-16 encoded string and determines if it is a
syntactically correct JSON text. Along the way, it creates a PHP variable.
It is implemented as a Pushdown Automaton; that means it is a finite state
machine with a stack.
*/
int
JSON_parser(zval *z, unsigned short p[], int length, int assoc TSRMLS_DC)
{
int b; /* the next character */
int c; /* the next character class */
int s; /* the next state */
json_parser the_json; /* the parser state */
int the_state = 0;
int the_index;
smart_str buf = {0};
smart_str key = {0};
int type = -1;
unsigned short utf16;
JSON(the_top) = -1;
push(&the_json, z, MODE_DONE);
for (the_index = 0; the_index < length; the_index += 1) {
b = p[the_index];
if ((b & 127) == b) {
c = ascii_class[b];
if (c <= S_ERR) {
FREE_BUFFERS();
return false;
}
} else {
c = S_ETC;
}
/*
Get the next state from the transition table.
*/
s = state_transition_table[the_state][c];
if (s < 0) {
/*
Perform one of the predefined actions.
*/
switch (s) {
/*
empty }
*/
case -9:
if (!pop(&the_json, z, MODE_KEY)) {
FREE_BUFFERS();
return false;
}
the_state = 9;
break;
/*
{
*/
case -8:
if (!push(&the_json, z, MODE_KEY)) {
FREE_BUFFERS();
return false;
}
the_state = 1;
if (JSON(the_top) > 0)
{
zval *obj;
if (JSON(the_top) == 1)
{
obj = z;
}
else
{
ALLOC_INIT_ZVAL(obj);
}
if (!assoc)
{
object_init(obj);
}
else
{
array_init(obj);
}
JSON(the_zstack)[JSON(the_top)] = obj;
if (JSON(the_top) > 1)
{
attach_zval(&the_json, JSON(the_top-1), JSON(the_top), &key, assoc TSRMLS_CC);
}
JSON_RESET_TYPE();
}
break;
/*
}
*/
case -7:
if (type != -1 &&
(JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
JSON(the_stack)[JSON(the_top)] == MODE_ARRAY))
{
zval *mval;
smart_str_0(&buf);
json_create_zval(&mval, &buf, type);
if (!assoc)
{
add_property_zval(JSON(the_zstack)[JSON(the_top)], key.c, mval);
#if PHP_MAJOR_VERSION >= 5
ZVAL_DELREF(mval);
#endif
}
else
{
add_assoc_zval(JSON(the_zstack)[JSON(the_top)], key.c, mval);
}
key.len = 0;
buf.len = 0;
JSON_RESET_TYPE();
}
if (!pop(&the_json, z, MODE_OBJECT)) {
FREE_BUFFERS();
return false;
}
the_state = 9;
break;
/*
[
*/
case -6:
if (!push(&the_json, z, MODE_ARRAY)) {
FREE_BUFFERS();
return false;
}
the_state = 2;
if (JSON(the_top) > 0)
{
zval *arr;
if (JSON(the_top) == 1)
{
arr = z;
}
else
{
ALLOC_INIT_ZVAL(arr);
}
array_init(arr);
JSON(the_zstack)[JSON(the_top)] = arr;
if (JSON(the_top) > 1)
{
attach_zval(&the_json, JSON(the_top-1), JSON(the_top), &key, assoc TSRMLS_CC);
}
JSON_RESET_TYPE();
}
break;
/*
]
*/
case -5:
{
if (type != -1 &&
(JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
JSON(the_stack)[JSON(the_top)] == MODE_ARRAY))
{
zval *mval;
smart_str_0(&buf);
json_create_zval(&mval, &buf, type);
add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
buf.len = 0;
JSON_RESET_TYPE();
}
if (!pop(&the_json, z, MODE_ARRAY)) {
FREE_BUFFERS();
return false;
}
the_state = 9;
}
break;
/*
"
*/
case -4:
switch (JSON(the_stack)[JSON(the_top)]) {
case MODE_KEY:
the_state = 27;
smart_str_0(&buf);
SWAP_BUFFERS(buf, key);
JSON_RESET_TYPE();
break;
case MODE_ARRAY:
case MODE_OBJECT:
the_state = 9;
break;
default:
FREE_BUFFERS();
return false;
}
break;
/*
,
*/
case -3:
{
zval *mval;
if (type != -1 &&
(JSON(the_stack)[JSON(the_top)] == MODE_OBJECT ||
JSON(the_stack[JSON(the_top)]) == MODE_ARRAY))
{
smart_str_0(&buf);
json_create_zval(&mval, &buf, type);
}
switch (JSON(the_stack)[JSON(the_top)]) {
case MODE_OBJECT:
if (pop(&the_json, z, MODE_OBJECT) && push(&the_json, z, MODE_KEY)) {
if (type != -1)
{
if (!assoc)
{
add_property_zval(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : "_empty_"), mval);
#if PHP_MAJOR_VERSION >= 5
ZVAL_DELREF(mval);
#endif
}
else
{
add_assoc_zval(JSON(the_zstack)[JSON(the_top)], (key.len ? key.c : "_empty_"), mval);
}
key.len = 0;
}
the_state = 29;
}
break;
case MODE_ARRAY:
if (type != -1)
{
add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
}
the_state = 28;
break;
default:
FREE_BUFFERS();
return false;
}
buf.len = 0;
JSON_RESET_TYPE();
}
break;
/*
:
*/
case -2:
if (pop(&the_json, z, MODE_KEY) && push(&the_json, z, MODE_OBJECT)) {
the_state = 28;
break;
}
/*
syntax error
*/
case -1:
{
FREE_BUFFERS();
return false;
}
}
} else {
/*
Change the state and iterate.
*/
if (type == IS_STRING)
{
if (s == 3 && the_state != 8)
{
if (the_state != 4)
{
utf16_to_utf8(&buf, b);
}
else
{
switch (b)
{
case 'b':
smart_str_appendc(&buf, '\b');
break;
case 't':
smart_str_appendc(&buf, '\t');
break;
case 'n':
smart_str_appendc(&buf, '\n');
break;
case 'f':
smart_str_appendc(&buf, '\f');
break;
case 'r':
smart_str_appendc(&buf, '\r');
break;
default:
utf16_to_utf8(&buf, b);
break;
}
}
}
else if (s == 6)
{
utf16 = dehexchar(b) << 12;
}
else if (s == 7)
{
utf16 += dehexchar(b) << 8;
}
else if (s == 8)
{
utf16 += dehexchar(b) << 4;
}
else if (s == 3 && the_state == 8)
{
utf16 += dehexchar(b);
utf16_to_utf8(&buf, utf16);
}
}
else if (type < IS_LONG && (c == S_DIG || c == S_ZER))
{
type = IS_LONG;
smart_str_appendc(&buf, b);
}
else if (type == IS_LONG && s == 24)
{
type = IS_DOUBLE;
smart_str_appendc(&buf, b);
}
else if (type < IS_DOUBLE && c == S_DOT)
{
type = IS_DOUBLE;
smart_str_appendc(&buf, b);
}
else if (type < IS_STRING && c == S_QUO)
{
type = IS_STRING;
}
else if (type < IS_BOOL && ((the_state == 12 && s == 9) || (the_state == 16 && s == 9)))
{
type = IS_BOOL;
}
else if (type < IS_NULL && the_state == 19 && s == 9)
{
type = IS_NULL;
}
else if (type != IS_STRING && c > S_WSP)
{
utf16_to_utf8(&buf, b);
}
the_state = s;
}
}
FREE_BUFFERS();
return the_state == 9 && pop(&the_json, z, MODE_DONE);
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4
* vim<600: noet sw=4 ts=4
*/

8
ext/json/JSON_parser.h

@ -0,0 +1,8 @@
/* JSON_checker.h */
#include "php.h"
#include "ext/standard/php_smart_str.h"
static char digits[] = "0123456789abcdef";
extern int JSON_parser(zval *z, unsigned short p[], int length, int assoc TSRMLS_DC);

76
ext/json/README

@ -0,0 +1,76 @@
json 1.2.0
==========
This extension implements the JavaScript Object Notation (JSON)
data-interchange format as specified in [0].
Two functions are implemented: encoding and decoding. The decoding
is handled by a parser based on JSON_checker[1] by Douglas Crockford.
Function overview
-----------------
string json_encode ( mixed value )
json_encode returns a string containing the JSON representation of value.
value can be any type except a resource.
mixed json_decode ( string json, [bool assoc] )
json_decode takes a JSON string and converts it into a PHP variable.
When assoc is given, and evaluates to TRUE, json_decode() will return
any objects as associative arrays.
Example usage
-------------
$arr = array("a"=>1,"b"=>2,"c"=>3,"d"=>4,"e"=>5);
echo json_encode($arr);
---> {"a":1,"b":2,"c":3,"d":4,"e":5}
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
---> object(stdClass)#1 (5) {
["a"]=>
int(1)
["b"]=>
int(2)
["c"]=>
int(3)
["d"]=>
int(4)
["e"]=>
int(5)
}
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json, true));
---> array(5) {
["a"]=>
int(1)
["b"]=>
int(2)
["c"]=>
int(3)
["d"]=>
int(4)
["e"]=>
int(5)
}
Authors
-------
Omar Kilani <omar@php.net>
---
[0] http://www.crockford.com/JSON/draft-jsonorg-json-00.txt
[1] http://www.crockford.com/JSON/JSON_checker/

88
ext/json/config.m4

@ -0,0 +1,88 @@
dnl
dnl $Id$
dnl
AC_DEFUN([PHP_JSON_ADD_SOURCES], [
PHP_JSON_SOURCES="$PHP_JSON_SOURCES $1"
])
AC_DEFUN([PHP_JSON_ADD_BASE_SOURCES], [
PHP_JSON_BASE_SOURCES="$PHP_JSON_BASE_SOURCES $1"
])
AC_DEFUN([PHP_JSON_ADD_BUILD_DIR], [
PHP_JSON_EXTRA_BUILD_DIRS="$PHP_JSON_EXTRA_BUILD_DIRS $1"
])
AC_DEFUN([PHP_JSON_ADD_INCLUDE], [
PHP_JSON_EXTRA_INCLUDES="$PHP_JSON_EXTRA_INCLUDES $1"
])
AC_DEFUN([PHP_JSON_ADD_CONFIG_HEADER], [
PHP_JSON_EXTRA_CONFIG_HEADERS="$PHP_JSON_EXTRA_CONFIG_HEADERS $1"
])
AC_DEFUN([PHP_JSON_ADD_CFLAG], [
PHP_JSON_CFLAGS="$PHP_JSON_CFLAGS $1"
])
AC_DEFUN([PHP_JSON_EXTENSION], [
PHP_NEW_EXTENSION(json, $PHP_JSON_SOURCES, $ext_shared,, $PHP_JSON_CFLAGS)
PHP_SUBST(JSON_SHARED_LIBADD)
for dir in $PHP_JSON_EXTRA_BUILD_DIRS; do
PHP_ADD_BUILD_DIR([$ext_builddir/$dir], 1)
done
for dir in $PHP_JSON_EXTRA_INCLUDES; do
PHP_ADD_INCLUDE([$ext_srcdir/$dir])
PHP_ADD_INCLUDE([$ext_builddir/$dir])
done
if test "$ext_shared" = "no"; then
PHP_ADD_SOURCES(PHP_EXT_DIR(json), $PHP_JSON_BASE_SOURCES,$PHP_JSON_CFLAGS)
out="php_config.h"
else
PHP_ADD_SOURCES_X(PHP_EXT_DIR(json),$PHP_JSON_BASE_SOURCES,$PHP_JSON_CFLAGS,shared_objects_json,yes)
if test -f "$ext_builddir/config.h.in"; then
out="$abs_builddir/config.h"
else
out="php_config.h"
fi
fi
for cfg in $PHP_JSON_EXTRA_CONFIG_HEADERS; do
cat > $ext_builddir/$cfg <<EOF
#include "$out"
EOF
done
])
AC_DEFUN([PHP_JSON_SETUP_JSON_CHECKER], [
PHP_JSON_ADD_SOURCES([
utf8_to_utf16.c
utf8_decode.c
JSON_parser.c
])
])
dnl
dnl Main config
dnl
PHP_ARG_WITH(json, whether to enable JavaScript Object Serialization support,
[ --with-json Enable JavaScript Object Serialization support])
if test "$PHP_JSON" != "no"; then
AC_DEFINE([HAVE_JSON],1,[whether to have JavaScript Object Serialization support])
AC_HEADER_STDC
PHP_JSON_ADD_BASE_SOURCES([json.c])
dnl json_c is required
PHP_JSON_SETUP_JSON_CHECKER
PHP_JSON_EXTENSION
dnl PHP_INSTALL_HEADERS([ext/json], [json_c])
fi
# vim600: sts=2 sw=2 et

10
ext/json/config.w32

@ -0,0 +1,10 @@
// $Id$
// vim:ft=javascript
ARG_WITH("json", "JavaScript Object Serialization support", "no");
if (PHP_JSON != "no") {
EXTENSION('json', 'json.c', PHP_JSON_SHARED, "");
ADD_SOURCES(configure_module_dirname, "JSON_parser.c utf8_decode.c utf8_to_utf16.c", "json");
}

449
ext/json/json.c

@ -0,0 +1,449 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+
| 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. |
+----------------------------------------------------------------------+
| Author: Omar Kilani <omar@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_smart_str.h"
#include "utf8_to_utf16.h"
#include "JSON_parser.h"
#include "php_json.h"
/* If you declare any globals in php_json.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(json)
*/
/* True global resources - no need for thread safety here */
static int le_json;
/* {{{ json_functions[]
*
* Every user visible function must have an entry in json_functions[].
*/
function_entry json_functions[] = {
PHP_FE(json_encode, NULL)
PHP_FE(json_decode, NULL)
{NULL, NULL, NULL} /* Must be the last line in json_functions[] */
};
/* }}} */
/* {{{ json_module_entry
*/
zend_module_entry json_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"json",
json_functions,
NULL,
NULL,
NULL,
NULL,
PHP_MINFO(json),
#if ZEND_MODULE_API_NO >= 20010901
PHP_JSON_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};
/* }}} */
#ifdef COMPILE_DL_JSON
ZEND_GET_MODULE(json)
#endif
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(json)
{
php_info_print_table_start();
php_info_print_table_row(2, "json support", "enabled");
php_info_print_table_row(2, "json version", PHP_JSON_VERSION);
php_info_print_table_end();
}
/* }}} */
static void json_encode_r(smart_str *buf, zval *val TSRMLS_DC);
static void json_escape_string(smart_str *buf, char *s, int len TSRMLS_DC);
static int json_determine_array_type(zval **val TSRMLS_DC) {
int i;
HashTable *myht;
if (Z_TYPE_PP(val) == IS_ARRAY) {
myht = HASH_OF(*val);
} else {
myht = Z_OBJPROP_PP(val);
return 1;
}
i = myht ? zend_hash_num_elements(myht) : 0;
if (i > 0) {
char *key;
ulong index, idx;
uint key_len;
HashPosition pos;
zend_hash_internal_pointer_reset_ex(myht, &pos);
idx = 0;
for (;; zend_hash_move_forward_ex(myht, &pos)) {
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
if (i == HASH_KEY_NON_EXISTANT)
break;
if (i == HASH_KEY_IS_STRING) {
return 1;
} else {
if (index != idx) {
return 1;
}
}
idx++;
}
}
return 0;
}
static void json_encode_array(smart_str *buf, zval **val TSRMLS_DC) {
int i, r;
HashTable *myht;
if (Z_TYPE_PP(val) == IS_ARRAY) {
myht = HASH_OF(*val);
r = json_determine_array_type(val TSRMLS_CC);
} else {
myht = Z_OBJPROP_PP(val);
r = 1;
}
if (r == 0)
{
smart_str_appendc(buf, '[');
}
else
{
smart_str_appendc(buf, '{');
}
i = myht ? zend_hash_num_elements(myht) : 0;
if (i > 0) {
char *key;
zval **data;
ulong index;
uint key_len;
HashPosition pos;
int need_comma = 0;
zend_hash_internal_pointer_reset_ex(myht, &pos);
for (;; zend_hash_move_forward_ex(myht, &pos)) {
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
if (i == HASH_KEY_NON_EXISTANT)
break;
if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS) {
if (r == 0) {
if (need_comma) {
smart_str_appendc(buf, ',');
} else {
need_comma = 1;
}
json_encode_r(buf, *data TSRMLS_CC);
} else if (r == 1) {
if (i == HASH_KEY_IS_STRING) {
if (key[0] == '\0') {
/* Skip protected and private members. */
continue;
}
if (need_comma) {
smart_str_appendc(buf, ',');
} else {
need_comma = 1;
}
json_escape_string(buf, key, key_len - 1 TSRMLS_CC);
smart_str_appendc(buf, ':');
json_encode_r(buf, *data TSRMLS_CC);
} else {
if (need_comma) {
smart_str_appendc(buf, ',');
} else {
need_comma = 1;
}
smart_str_appendc(buf, '"');
smart_str_append_long(buf, (long) index);
smart_str_appendc(buf, '"');
smart_str_appendc(buf, ':');
json_encode_r(buf, *data TSRMLS_CC);
}
}
}
}
}
if (r == 0)
{
smart_str_appendc(buf, ']');
}
else
{
smart_str_appendc(buf, '}');
}
}
#define REVERSE16(us) (((us & 0xf) << 12) | (((us >> 4) & 0xf) << 8) | (((us >> 8) & 0xf) << 4) | ((us >> 12) & 0xf))
static void json_escape_string(smart_str *buf, char *s, int len TSRMLS_DC)
{
int pos = 0;
unsigned short us;
unsigned short *utf16;
if (len == 0)
{
smart_str_appendl(buf, "\"\"", 2);
return;
}
utf16 = (unsigned short *) emalloc(len * sizeof(unsigned short));
len = utf8_to_utf16(utf16, s, len);
if (len <= 0)
{
if (utf16)
{
efree(utf16);
}
smart_str_appendl(buf, "\"\"", 2);
return;
}
smart_str_appendc(buf, '"');
while(pos < len)
{
us = utf16[pos++];
switch (us)
{
case '"':
{
smart_str_appendl(buf, "\\\"", 2);
}
break;
case '\\':
{
smart_str_appendl(buf, "\\\\", 2);
}
break;
case '/':
{
smart_str_appendl(buf, "\\/", 2);
}
break;
case '\b':
{
smart_str_appendl(buf, "\\b", 2);
}
break;
case '\f':
{
smart_str_appendl(buf, "\\f", 2);
}
break;
case '\n':
{
smart_str_appendl(buf, "\\n", 2);
}
break;
case '\r':
{
smart_str_appendl(buf, "\\r", 2);
}
break;
case '\t':
{
smart_str_appendl(buf, "\\t", 2);
}
break;
default:
{
if (us < ' ' || (us & 127) == us)
{
smart_str_appendc(buf, (unsigned char) us);
}
else
{
smart_str_appendl(buf, "\\u", 2);
us = REVERSE16(us);
smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
us >>= 4;
smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
us >>= 4;
smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
us >>= 4;
smart_str_appendc(buf, digits[us & ((1 << 4) - 1)]);
}
}
break;
}
}
smart_str_appendc(buf, '"');
efree(utf16);
}
static void json_encode_r(smart_str *buf, zval *val TSRMLS_DC) {
switch (Z_TYPE_P(val)) {
case IS_NULL:
smart_str_appendl(buf, "null", 4);
break;
case IS_BOOL:
if (Z_BVAL_P(val))
{
smart_str_appendl(buf, "true", 4);
}
else
{
smart_str_appendl(buf, "false", 5);
}
break;
case IS_LONG:
smart_str_append_long(buf, Z_LVAL_P(val));
break;
case IS_DOUBLE:
{
char *d = NULL;
int len;
double dbl = Z_DVAL_P(val);
if (!zend_isinf(dbl) && !zend_isnan(dbl))
{
len = spprintf(&d, 0, "%.9g", dbl);
if (d)
{
smart_str_appendl(buf, d, len);
efree(d);
}
}
else
{
zend_error(E_WARNING, "[json] (json_encode_r) double %.9g does not conform to the JSON spec, encoded as 0.", dbl);
smart_str_appendc(buf, '0');
}
}
break;
case IS_STRING:
json_escape_string(buf, Z_STRVAL_P(val), Z_STRLEN_P(val) TSRMLS_CC);
break;
case IS_ARRAY:
case IS_OBJECT:
json_encode_array(buf, &val TSRMLS_CC);
break;
default:
zend_error(E_WARNING, "[json] (json_encode_r) type is unsupported, encoded as null.");
smart_str_appendl(buf, "null", 4);
break;
}
return;
}
PHP_FUNCTION(json_encode)
{
zval *parameter;
smart_str buf = {0};
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &parameter) == FAILURE) {
return;
}
json_encode_r(&buf, parameter TSRMLS_CC);
ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
smart_str_free(&buf);
}
PHP_FUNCTION(json_decode)
{
char *parameter;
int parameter_len, utf16_len;
zend_bool assoc = 0; /* return JS objects as PHP objects by default */
zval *z;
unsigned short *utf16;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &parameter, &parameter_len, &assoc) == FAILURE) {
return;
}
if (!parameter_len)
{
RETURN_NULL();
}
utf16 = (unsigned short *) emalloc((parameter_len+1) * sizeof(unsigned short));
utf16_len = utf8_to_utf16(utf16, parameter, parameter_len);
if (utf16_len <= 0)
{
if (utf16)
{
efree(utf16);
}
RETURN_NULL();
}
ALLOC_INIT_ZVAL(z);
if (JSON_parser(z, utf16, utf16_len, assoc TSRMLS_CC))
{
*return_value = *z;
FREE_ZVAL(z);
efree(utf16);
}
else
{
zval_dtor(z);
FREE_ZVAL(z);
efree(utf16);
RETURN_NULL();
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4
* vim<600: noet sw=4 ts=4
*/

135
ext/json/json.dsp

@ -0,0 +1,135 @@
# Microsoft Developer Studio Project File - Name="json" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=json - Win32 Debug_TS
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "json.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "json.mak" CFG="json - Win32 Debug_TS"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "json - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "json - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "json - Win32 Debug_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_TS"
# PROP BASE Intermediate_Dir "Debug_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_TS"
# PROP Intermediate_Dir "Debug_TS"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JSON_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "json_c" /D HAVE_JSON=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D ZEND_DEBUG=1 /D ZTS=1 /D COMPILE_DL_JSON=1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JSON_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x1009 /d "_DEBUG"
# ADD RSC /l 0x1009 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 iconv.lib php4ts_debug.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"..\..\Debug_TS/php_json.dll" /pdbtype:sept /libpath:"..\..\Debug_TS"
!ELSEIF "$(CFG)" == "json - Win32 Release_TS"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_TS"
# PROP BASE Intermediate_Dir "Release_TS"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TS"
# PROP Intermediate_Dir "Release_TS"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JSON_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\TSRM" /I "json_c" /D HAVE_JSON=1 /D "ZEND_WIN32" /D ZEND_DEBUG=0 /D "PHP_WIN32" /D ZTS=1 /D COMPILE_DL_JSON=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JSON_EXPORTS" /D "HAVE_FCNTL_H" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x1009 /d "NDEBUG"
# ADD RSC /l 0x1009 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 iconv.lib php4ts.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_json.dll" /libpath:"..\..\Release_TS"
!ENDIF
# Begin Target
# Name "json - Win32 Debug_TS"
# Name "json - Win32 Release_TS"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=".\json.c"
# End Source File
# Begin Source File
SOURCE=.\JSON_parser.c
# End Source File
# Begin Source File
SOURCE=.\JSON_parser.h
# End Source File
# Begin Source File
SOURCE=.\utf8_decode.c
# End Source File
# Begin Source File
SOURCE=.\utf8_decode.h
# End Source File
# Begin Source File
SOURCE=.\utf8_to_utf16.c
# End Source File
# Begin Source File
SOURCE=.\utf8_to_utf16.h
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\php_json.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

152
ext/json/package.xml

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE package SYSTEM "../pear/package.dtd">
<package>
<dep type="php" rel="ge" version="4.3.0" optional="no"/>
<name>json</name>
<summary>JavaScript Object Notation</summary>
<maintainers>
<maintainer>
<user>omar</user>
<name>Omar Kilani</name>
<email>omar@php.net</email>
<role>lead</role>
</maintainer>
</maintainers>
<description>
Support for JSON (JavaScript Object Notation) serialization.
</description>
<license>PHP 3.01</license>
<release>
<state>stable</state>
<version>1.2.1</version>
<date>2006-03-18</date>
<notes>
Fix PECL bug #7147 - rework handling of comma insertion while encoding.
Add tests to package.xml
</notes>
</release>
<configureoptions>
</configureoptions>
<filelist>
<file role="doc" name="README" />
<file role="src" name="config.m4" />
<file role="src" name="config.w32" />
<file role="src" name="json.dsp" />
<file role="src" name="json.c" />
<file role="src" name="JSON_parser.c" />
<file role="src" name="JSON_parser.h" />
<file role="src" name="php_json.h" />
<file role="src" name="utf8_decode.c" />
<file role="src" name="utf8_decode.h" />
<file role="src" name="utf8_to_utf16.c" />
<file role="src" name="utf8_to_utf16.h" />
<dir role="test" name="tests">
<file role="test" name="fail001.phpt" />
<file role="test" name="pass001.phpt" />
<file role="test" name="pass001.1.phpt" />
<file role="test" name="pass002.phpt" />
<file role="test" name="pass003.phpt" />
</dir>
</filelist>
<changelog>
<release>
<state>stable</state>
<version>1.0.0</version>
<date>2005-04-01</date>
<notes>
Initial release.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.1</version>
<date>2005-06-10</date>
<notes>
Fixed non-linear and mixed type array index issues, fixed issues with escaping \\, forked json-c and added Unicode support.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.2</version>
<date>2005-06-11</date>
<notes>
Fixed issues with object reference counts under PHP4.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.3</version>
<date>2005-06-15</date>
<notes>
Fixed json-c string corruption issues under Mac OS X and FreeBSD.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.4</version>
<date>2005-06-15</date>
<notes>
Changes in 1.0.4 released with 1.0.5.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.5</version>
<date>2005-06-16</date>
<notes>
Changed spacing in json-c encoding, added optional assoc (boolean) parameter to json_decode to decode as associative array instead of object, fixed issues with escaping /.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.6</version>
<date>2005-08-05</date>
<notes>
Fixed issues with exporting private and protected class members.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.7</version>
<date>2005-09-07</date>
<notes>
Fixed issues with negative array keys, modified json-c to return an error on unquoted object key names instead of going into an infinite loop.
</notes>
</release>
<release>
<state>stable</state>
<version>1.0.8</version>
<date>2005-12-01</date>
<notes>
Changed license to LGPL, modified build system to allow static compilation into PHP, added strndup check for json-c.
</notes>
</release>
<release>
<state>stable</state>
<version>1.1.0</version>
<date>2005-12-04</date>
<notes>
Port to Win32.
</notes>
</release>
<release>
<state>stable</state>
<version>1.1.1</version>
<date>2006-01-12</date>
<notes>
Cleanup and TSRM performance fixes by rasmus.
</notes>
</release>
<release>
<state>stable</state>
<version>1.2.0</version>
<date>2006-03-15</date>
<notes>
Complete rewrite using JSON_checker as the base for the parser. Implements the JSON specification. 3-8x faster on encodes and 1.2x-4x faster on decodes.
</notes>
</release>
</changelog>
</package>
<!--
vim:et:ts=1:sw=1
-->

60
ext/json/php_json.h

@ -0,0 +1,60 @@
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+
| 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. |
+----------------------------------------------------------------------+
| Author: Omar Kilani <omar@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef PHP_JSON_H
#define PHP_JSON_H
#define PHP_JSON_VERSION "1.2.1"
extern zend_module_entry json_module_entry;
#define phpext_json_ptr &json_module_entry
#ifdef PHP_WIN32
#define PHP_JSON_API __declspec(dllexport)
#else
#define PHP_JSON_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
PHP_MINFO_FUNCTION(json);
PHP_FUNCTION(json_encode);
PHP_FUNCTION(json_decode);
#ifdef ZTS
#define JSON_G(v) TSRMG(json_globals_id, zend_json_globals *, v)
#else
#define JSON_G(v) (json_globals.v)
#endif
#endif /* PHP_JSON_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

166
ext/json/tests/fail001.phpt

@ -0,0 +1,166 @@
--TEST--
JSON Test Pattern fail1 -> fail24
http://www.crockford.com/JSON/JSON_checker/test/fail*.json
--SKIPIF--
<?php
if (!extension_loaded('json')) die('skip: json extension not available');
?>
--FILE--
<?php
$tests = array('"A JSON payload should be an object or array, not a string."',
'["Unclosed array"',
'{unquoted_key: "keys must be quoted}',
'["extra comma",]',
'["double extra comma",,]',
'[ , "<-- missing value"]',
'["Comma after the close"],',
'["Extra close"]]',
'{"Extra comma": true,}',
'{"Extra value after close": true} "misplaced quoted value"',
'{"Illegal expression": 1 + 2}',
'{"Illegal invocation": alert()}',
'{"Numbers cannot have leading zeroes": 013}',
'{"Numbers cannot be hex": 0x14}',
'["Illegal backslash escape: \\x15"]',
'["Illegal backslash escape: \\\'"]',
'["Illegal backslash escape: \\017"]',
'[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
'{"Missing colon" null}',
'{"Double colon":: null}',
'{"Comma instead of colon", null}',
'["Colon instead of comma": false]',
'["Bad value", truth]',
"['single quote']");
foreach ($tests as $test)
{
echo 'Testing: ' . $test . "\n";
echo "AS OBJECT\n";
var_dump(json_decode($test));
echo "AS ARRAY\n";
var_dump(json_decode($test, true));
}
?>
--EXPECT--
Testing: "A JSON payload should be an object or array, not a string."
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Unclosed array"
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {unquoted_key: "keys must be quoted}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["extra comma",]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["double extra comma",,]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: [ , "<-- missing value"]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Comma after the close"],
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Extra close"]]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Extra comma": true,}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Extra value after close": true} "misplaced quoted value"
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Illegal expression": 1 + 2}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Illegal invocation": alert()}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Numbers cannot have leading zeroes": 013}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Numbers cannot be hex": 0x14}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Illegal backslash escape: \x15"]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Illegal backslash escape: \'"]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Illegal backslash escape: \017"]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Missing colon" null}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Double colon":: null}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: {"Comma instead of colon", null}
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Colon instead of comma": false]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ["Bad value", truth]
AS OBJECT
NULL
AS ARRAY
NULL
Testing: ['single quote']
AS OBJECT
NULL
AS ARRAY
NULL

895
ext/json/tests/pass001.1.phpt

@ -0,0 +1,895 @@
--TEST--
JSON Test Pattern pass1.1
Modified to test unescaped UNICODE as keys and values.
Modified to test numbers with exponents without a decimal point.
Modified to test empty string values.
Modified to test a mix of integers and strings as keys.
http://www.crockford.com/JSON/JSON_checker/test/pass1.json
--SKIPIF--
<?php
if (!extension_loaded('json')) die('skip: json extension not available');
?>
--FILE--
<?php
// Expect warnings about INF.
ini_set("error_reporting", E_ALL & ~E_WARNING);
$test = "
[
\"JSON Test Pattern pass1\",
{\"object with 1 member\":[\"array with 1 element\"]},
{},
[],
-42,
true,
false,
null,
{
\"integer\": 1234567890,
\"real\": -9876.543210,
\"e\": 0.123456789e-12,
\"E\": 1.234567890E+34,
\"\": 23456789012E666,
\"E no .\": 4E12,
\"zero\": 0,
\"one\": 1,
\"space\": \" \",
\"quote\": \"\\\"\",
\"backslash\": \"\\\\\",
\"controls\": \"\\b\\f\\n\\r\\t\",
\"slash\": \"/ & \\/\",
\"alpha\": \"abcdefghijklmnopqrstuvwyz\",
\"ALPHA\": \"ABCDEFGHIJKLMNOPQRSTUVWYZ\",
\"digit\": \"0123456789\",
\"special\": \"`1~!@#$%^&*()_+-={':[,]}|;.</>?\",
\"hex\": \"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A\",
\"unicode\": \"\\u30d7\\u30ec\\u30b9\\u30ad\\u30c3\\u30c8\",
\"プレスキット\": \"プレスキット\",
\"empty_string\": \"\",
\"true\": true,
\"false\": false,
\"null\": null,
\"array\":[ ],
\"object\":{ },
\"123\":{\"456\":{\"abc\":{\"789\":\"def\",\"012\":[1,2,\"5\",500],\"ghi\":[1,2,\"five\",50,\"sixty\"]}}},
\"address\": \"50 St. James Street\",
\"url\": \"http://www.JSON.org/\",
\"comment\": \"// /* <!-- --\",
\"# -- --> */\": \" \",
\" s p a c e d \" :[1,2 , 3
,
4 , 5 , 6 ,7 ],
\"compact\": [1,2,3,4,5,6,7],
\"jsontext\": \"{\\\"object with 1 member\\\":[\\\"array with 1 element\\\"]}\",
\"quotes\": \"&#34; \\u0022 %22 0x22 034 &#x22;\",
\"\\/\\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?\"
: \"A key can be any string\"
},
0.5 ,98.6
,
99.44
,
1066
,\"rosebud\"]
";
echo 'Testing: ' . $test . "\n";
echo "DECODE: AS OBJECT\n";
$obj = json_decode($test);
var_dump($obj);
echo "DECODE: AS ARRAY\n";
$arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
$obj_enc = json_encode($obj);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
$arr_enc = json_encode($arr);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
$obj = json_decode($obj_enc);
var_dump($obj);
echo "DECODE AGAIN: AS ARRAY\n";
$arr = json_decode($arr_enc, true);
var_dump($arr);
?>
--EXPECT--
Testing:
[
"JSON Test Pattern pass1",
{"object with 1 member":["array with 1 element"]},
{},
[],
-42,
true,
false,
null,
{
"integer": 1234567890,
"real": -9876.543210,
"e": 0.123456789e-12,
"E": 1.234567890E+34,
"": 23456789012E666,
"E no .": 4E12,
"zero": 0,
"one": 1,
"space": " ",
"quote": "\"",
"backslash": "\\",
"controls": "\b\f\n\r\t",
"slash": "/ & \/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
"unicode": "\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8",
"プレスキット": "プレスキット",
"empty_string": "",
"true": true,
"false": false,
"null": null,
"array":[ ],
"object":{ },
"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},
"address": "50 St. James Street",
"url": "http://www.JSON.org/",
"comment": "// /* <!-- --",
"# -- --> */": " ",
" s p a c e d " :[1,2 , 3
,
4 , 5 , 6 ,7 ],
"compact": [1,2,3,4,5,6,7],
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
: "A key can be any string"
},
0.5 ,98.6
,
99.44
,
1066
,"rosebud"]
DECODE: AS OBJECT
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
object(stdClass)#1 (1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
object(stdClass)#2 (0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
object(stdClass)#3 (36) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
float(INF)
["E no ."]=>
float(4.0E+12)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["unicode"]=>
string(18) "プレスキット"
["プレスキット"]=>
string(18) "プレスキット"
["empty_string"]=>
string(0) ""
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
object(stdClass)#4 (0) {
}
["123"]=>
object(stdClass)#5 (1) {
["456"]=>
object(stdClass)#6 (1) {
["abc"]=>
object(stdClass)#7 (3) {
["789"]=>
string(3) "def"
["012"]=>
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(1) "5"
[3]=>
int(500)
}
["ghi"]=>
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(4) "five"
[3]=>
int(50)
[4]=>
string(5) "sixty"
}
}
}
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}
DECODE: AS ARRAY
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
array(1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
array(0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
array(36) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
float(INF)
["E no ."]=>
float(4.0E+12)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["unicode"]=>
string(18) "プレスキット"
["プレスキット"]=>
string(18) "プレスキット"
["empty_string"]=>
string(0) ""
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
array(0) {
}
[123]=>
array(1) {
[456]=>
array(1) {
["abc"]=>
array(3) {
[789]=>
string(3) "def"
["012"]=>
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(1) "5"
[3]=>
int(500)
}
["ghi"]=>
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(4) "five"
[3]=>
int(50)
[4]=>
string(5) "sixty"
}
}
}
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}
ENCODE: FROM OBJECT
["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"E no .":4.0e+12,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":{},"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"&#34; \" %22 0x22 034 &#x22;","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"]
ENCODE: FROM ARRAY
["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},[],[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"E no .":4.0e+12,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","unicode":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8":"\u30d7\u30ec\u30b9\u30ad\u30c3\u30c8","empty_string":"","true":true,"false":false,"null":null,"array":[],"object":[],"123":{"456":{"abc":{"789":"def","012":[1,2,"5",500],"ghi":[1,2,"five",50,"sixty"]}}},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"&#34; \" %22 0x22 034 &#x22;","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"]
DECODE AGAIN: AS OBJECT
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
object(stdClass)#8 (1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
object(stdClass)#9 (0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
object(stdClass)#10 (36) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
int(0)
["E no ."]=>
float(4.0E+12)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["unicode"]=>
string(18) "プレスキット"
["プレスキット"]=>
string(18) "プレスキット"
["empty_string"]=>
string(0) ""
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
object(stdClass)#11 (0) {
}
["123"]=>
object(stdClass)#12 (1) {
["456"]=>
object(stdClass)#13 (1) {
["abc"]=>
object(stdClass)#14 (3) {
["789"]=>
string(3) "def"
["012"]=>
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(1) "5"
[3]=>
int(500)
}
["ghi"]=>
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(4) "five"
[3]=>
int(50)
[4]=>
string(5) "sixty"
}
}
}
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}
DECODE AGAIN: AS ARRAY
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
array(1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
array(0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
array(36) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
int(0)
["E no ."]=>
float(4.0E+12)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["unicode"]=>
string(18) "プレスキット"
["プレスキット"]=>
string(18) "プレスキット"
["empty_string"]=>
string(0) ""
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
array(0) {
}
[123]=>
array(1) {
[456]=>
array(1) {
["abc"]=>
array(3) {
[789]=>
string(3) "def"
["012"]=>
array(4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(1) "5"
[3]=>
int(500)
}
["ghi"]=>
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
string(4) "five"
[3]=>
int(50)
[4]=>
string(5) "sixty"
}
}
}
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}

709
ext/json/tests/pass001.phpt

@ -0,0 +1,709 @@
--TEST--
JSON Test Pattern pass1
http://www.crockford.com/JSON/JSON_checker/test/pass1.json
--SKIPIF--
<?php
if (!extension_loaded('json')) die('skip: json extension not available');
?>
--FILE--
<?php
// Expect warnings about INF.
ini_set("error_reporting", E_ALL & ~E_WARNING);
$test = "
[
\"JSON Test Pattern pass1\",
{\"object with 1 member\":[\"array with 1 element\"]},
{},
[],
-42,
true,
false,
null,
{
\"integer\": 1234567890,
\"real\": -9876.543210,
\"e\": 0.123456789e-12,
\"E\": 1.234567890E+34,
\"\": 23456789012E666,
\"zero\": 0,
\"one\": 1,
\"space\": \" \",
\"quote\": \"\\\"\",
\"backslash\": \"\\\\\",
\"controls\": \"\\b\\f\\n\\r\\t\",
\"slash\": \"/ & \\/\",
\"alpha\": \"abcdefghijklmnopqrstuvwyz\",
\"ALPHA\": \"ABCDEFGHIJKLMNOPQRSTUVWYZ\",
\"digit\": \"0123456789\",
\"special\": \"`1~!@#$%^&*()_+-={':[,]}|;.</>?\",
\"hex\": \"\\u0123\\u4567\\u89AB\\uCDEF\\uabcd\\uef4A\",
\"true\": true,
\"false\": false,
\"null\": null,
\"array\":[ ],
\"object\":{ },
\"address\": \"50 St. James Street\",
\"url\": \"http://www.JSON.org/\",
\"comment\": \"// /* <!-- --\",
\"# -- --> */\": \" \",
\" s p a c e d \" :[1,2 , 3
,
4 , 5 , 6 ,7 ],
\"compact\": [1,2,3,4,5,6,7],
\"jsontext\": \"{\\\"object with 1 member\\\":[\\\"array with 1 element\\\"]}\",
\"quotes\": \"&#34; \\u0022 %22 0x22 034 &#x22;\",
\"\\/\\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?\"
: \"A key can be any string\"
},
0.5 ,98.6
,
99.44
,
1066
,\"rosebud\"]
";
echo 'Testing: ' . $test . "\n";
echo "DECODE: AS OBJECT\n";
$obj = json_decode($test);
var_dump($obj);
echo "DECODE: AS ARRAY\n";
$arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
$obj_enc = json_encode($obj);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
$arr_enc = json_encode($arr);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
$obj = json_decode($obj_enc);
var_dump($obj);
echo "DECODE AGAIN: AS ARRAY\n";
$arr = json_decode($arr_enc, true);
var_dump($arr);
?>
--EXPECT--
Testing:
[
"JSON Test Pattern pass1",
{"object with 1 member":["array with 1 element"]},
{},
[],
-42,
true,
false,
null,
{
"integer": 1234567890,
"real": -9876.543210,
"e": 0.123456789e-12,
"E": 1.234567890E+34,
"": 23456789012E666,
"zero": 0,
"one": 1,
"space": " ",
"quote": "\"",
"backslash": "\\",
"controls": "\b\f\n\r\t",
"slash": "/ & \/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
"true": true,
"false": false,
"null": null,
"array":[ ],
"object":{ },
"address": "50 St. James Street",
"url": "http://www.JSON.org/",
"comment": "// /* <!-- --",
"# -- --> */": " ",
" s p a c e d " :[1,2 , 3
,
4 , 5 , 6 ,7 ],
"compact": [1,2,3,4,5,6,7],
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
: "A key can be any string"
},
0.5 ,98.6
,
99.44
,
1066
,"rosebud"]
DECODE: AS OBJECT
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
object(stdClass)#1 (1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
object(stdClass)#2 (0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
object(stdClass)#3 (31) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
float(INF)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
object(stdClass)#4 (0) {
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}
DECODE: AS ARRAY
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
array(1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
array(0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
array(31) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
float(INF)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
array(0) {
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}
ENCODE: FROM OBJECT
["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},{},[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","true":true,"false":false,"null":null,"array":[],"object":{},"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"&#34; \" %22 0x22 034 &#x22;","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"]
ENCODE: FROM ARRAY
["JSON Test Pattern pass1",{"object with 1 member":["array with 1 element"]},[],[],-42,true,false,null,{"integer":1234567890,"real":-9876.54321,"e":1.23456789e-13,"E":1.23456789e+34,"_empty_":0,"zero":0,"one":1,"space":" ","quote":"\"","backslash":"\\","controls":"\b\f\n\r\t","slash":"\/ & \/","alpha":"abcdefghijklmnopqrstuvwyz","ALPHA":"ABCDEFGHIJKLMNOPQRSTUVWYZ","digit":"0123456789","special":"`1~!@#$%^&*()_+-={':[,]}|;.<\/>?","hex":"\u0123\u4567\u89ab\ucdef\uabcd\uef4a","true":true,"false":false,"null":null,"array":[],"object":[],"address":"50 St. James Street","url":"http:\/\/www.JSON.org\/","comment":"\/\/ \/* <!-- --","# -- --> *\/":" "," s p a c e d ":[1,2,3,4,5,6,7],"compact":[1,2,3,4,5,6,7],"jsontext":"{\"object with 1 member\":[\"array with 1 element\"]}","quotes":"&#34; \" %22 0x22 034 &#x22;","\/\\\"\ucafe\ubabe\uab98\ufcde\ubcda\uef4a\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',.\/<>?":"A key can be any string"},0.5,98.6,99.44,1066,"rosebud"]
DECODE AGAIN: AS OBJECT
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
object(stdClass)#5 (1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
object(stdClass)#6 (0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
object(stdClass)#7 (31) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
int(0)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
object(stdClass)#8 (0) {
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}
DECODE AGAIN: AS ARRAY
array(14) {
[0]=>
string(23) "JSON Test Pattern pass1"
[1]=>
array(1) {
["object with 1 member"]=>
array(1) {
[0]=>
string(20) "array with 1 element"
}
}
[2]=>
array(0) {
}
[3]=>
array(0) {
}
[4]=>
int(-42)
[5]=>
bool(true)
[6]=>
bool(false)
[7]=>
NULL
[8]=>
array(31) {
["integer"]=>
int(1234567890)
["real"]=>
float(-9876.54321)
["e"]=>
float(1.23456789E-13)
["E"]=>
float(1.23456789E+34)
["_empty_"]=>
int(0)
["zero"]=>
int(0)
["one"]=>
int(1)
["space"]=>
string(1) " "
["quote"]=>
string(1) """
["backslash"]=>
string(1) "\"
["controls"]=>
string(5) "
"
["slash"]=>
string(5) "/ & /"
["alpha"]=>
string(25) "abcdefghijklmnopqrstuvwyz"
["ALPHA"]=>
string(25) "ABCDEFGHIJKLMNOPQRSTUVWYZ"
["digit"]=>
string(10) "0123456789"
["special"]=>
string(31) "`1~!@#$%^&*()_+-={':[,]}|;.</>?"
["hex"]=>
string(17) "ģ䕧覫췯ꯍ"
["true"]=>
bool(true)
["false"]=>
bool(false)
["null"]=>
NULL
["array"]=>
array(0) {
}
["object"]=>
array(0) {
}
["address"]=>
string(19) "50 St. James Street"
["url"]=>
string(20) "http://www.JSON.org/"
["comment"]=>
string(13) "// /* <!-- --"
["# -- --> */"]=>
string(1) " "
[" s p a c e d "]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["compact"]=>
array(7) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
[6]=>
int(7)
}
["jsontext"]=>
string(49) "{"object with 1 member":["array with 1 element"]}"
["quotes"]=>
string(27) "&#34; " %22 0x22 034 &#x22;"
["/\"쫾몾ꮘﳞ볚
`1~!@#$%^&*()_+-=[]{}|;:',./<>?"]=>
string(23) "A key can be any string"
}
[9]=>
float(0.5)
[10]=>
float(98.6)
[11]=>
float(99.44)
[12]=>
int(1066)
[13]=>
string(7) "rosebud"
}

276
ext/json/tests/pass002.phpt

@ -0,0 +1,276 @@
--TEST--
JSON Test Pattern pass2
http://www.crockford.com/JSON/JSON_checker/test/pass2.json
--SKIPIF--
<?php
if (!extension_loaded('json')) die('skip: json extension not available');
?>
--FILE--
<?php
$test = '[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]';
echo 'Testing: ' . $test . "\n";
echo "DECODE: AS OBJECT\n";
$obj = json_decode($test);
var_dump($obj);
echo "DECODE: AS ARRAY\n";
$arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
$obj_enc = json_encode($obj);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
$arr_enc = json_encode($arr);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
$obj = json_decode($obj_enc);
var_dump($obj);
echo "DECODE AGAIN: AS ARRAY\n";
$arr = json_decode($arr_enc, true);
var_dump($arr);
?>
--EXPECT--
Testing: [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
DECODE: AS OBJECT
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
string(12) "Not too deep"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
DECODE: AS ARRAY
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
string(12) "Not too deep"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
ENCODE: FROM OBJECT
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
ENCODE: FROM ARRAY
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
DECODE AGAIN: AS OBJECT
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
string(12) "Not too deep"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
DECODE AGAIN: AS ARRAY
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(1) {
[0]=>
string(12) "Not too deep"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}

95
ext/json/tests/pass003.phpt

@ -0,0 +1,95 @@
--TEST--
JSON Test Pattern pass3
http://www.crockford.com/JSON/JSON_checker/test/pass3.json
--SKIPIF--
<?php
if (!extension_loaded('json')) die('skip: json extension not available');
?>
--FILE--
<?php
$test = '
{
"JSON Test Pattern pass3": {
"The outermost value": "must be an object or array.",
"In this test": "It is an object."
}
}
';
echo 'Testing: ' . $test . "\n";
echo "DECODE: AS OBJECT\n";
$obj = json_decode($test);
var_dump($obj);
echo "DECODE: AS ARRAY\n";
$arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
$obj_enc = json_encode($obj);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
$arr_enc = json_encode($arr);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
$obj = json_decode($obj_enc);
var_dump($obj);
echo "DECODE AGAIN: AS ARRAY\n";
$arr = json_decode($arr_enc, true);
var_dump($arr);
?>
--EXPECT--
Testing:
{
"JSON Test Pattern pass3": {
"The outermost value": "must be an object or array.",
"In this test": "It is an object."
}
}
DECODE: AS OBJECT
object(stdClass)#1 (1) {
["JSON Test Pattern pass3"]=>
object(stdClass)#2 (2) {
["The outermost value"]=>
string(27) "must be an object or array."
["In this test"]=>
string(16) "It is an object."
}
}
DECODE: AS ARRAY
array(1) {
["JSON Test Pattern pass3"]=>
array(2) {
["The outermost value"]=>
string(27) "must be an object or array."
["In this test"]=>
string(16) "It is an object."
}
}
ENCODE: FROM OBJECT
{"JSON Test Pattern pass3":{"The outermost value":"must be an object or array.","In this test":"It is an object."}}
ENCODE: FROM ARRAY
{"JSON Test Pattern pass3":{"The outermost value":"must be an object or array.","In this test":"It is an object."}}
DECODE AGAIN: AS OBJECT
object(stdClass)#3 (1) {
["JSON Test Pattern pass3"]=>
object(stdClass)#4 (2) {
["The outermost value"]=>
string(27) "must be an object or array."
["In this test"]=>
string(16) "It is an object."
}
}
DECODE AGAIN: AS ARRAY
array(1) {
["JSON Test Pattern pass3"]=>
array(2) {
["The outermost value"]=>
string(27) "must be an object or array."
["In this test"]=>
string(16) "It is an object."
}
}

179
ext/json/utf8_decode.c

@ -0,0 +1,179 @@
/* utf8_decode.c */
/* 2005-12-25 */
/*
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utf8_decode.h"
/*
Very Strict UTF-8 Decoder
UTF-8 is a multibyte character encoding of Unicode. A character can be
represented by 1-4 bytes. The bit pattern of the first byte indicates the
number of continuation bytes.
Most UTF-8 decoders tend to be lenient, attempting to recover as much
information as possible, even from badly encoded input. This UTF-8
decoder is not lenient. It will reject input which does not include
proper continuation bytes. It will reject aliases (or suboptimal
codings). It will reject surrogates. (Surrogate encoding should only be
used with UTF-16.)
Code Contination Minimum Maximum
0xxxxxxx 0 0 127
10xxxxxx error
110xxxxx 1 128 2047
1110xxxx 2 2048 65535 excluding 55296 - 57343
11110xxx 3 65536 1114111
11111xxx error
*/
/*
Get the next byte. It returns UTF8_END if there are no more bytes.
*/
static int
get(json_utf8_decode *utf8)
{
int c;
if (utf8->the_index >= utf8->the_length) {
return UTF8_END;
}
c = utf8->the_input[utf8->the_index] & 0xFF;
utf8->the_index += 1;
return c;
}
/*
Get the 6-bit payload of the next continuation byte.
Return UTF8_ERROR if it is not a contination byte.
*/
static int
cont(json_utf8_decode *utf8)
{
int c = get(utf8);
return ((c & 0xC0) == 0x80) ? (c & 0x3F) : UTF8_ERROR;
}
/*
Initialize the UTF-8 decoder. The decoder is not reentrant,
*/
void
utf8_decode_init(json_utf8_decode *utf8, char p[], int length)
{
utf8->the_index = 0;
utf8->the_input = p;
utf8->the_length = length;
utf8->the_char = 0;
utf8->the_byte = 0;
}
/*
Get the current byte offset. This is generally used in error reporting.
*/
int
utf8_decode_at_byte(json_utf8_decode *utf8)
{
return utf8->the_byte;
}
/*
Get the current character offset. This is generally used in error reporting.
The character offset matches the byte offset if the text is strictly ASCII.
*/
int
utf8_decode_at_character(json_utf8_decode *utf8)
{
return utf8->the_char > 0 ? utf8->the_char - 1 : 0;
}
/*
Extract the next character.
Returns: the character (between 0 and 1114111)
or UTF8_END (the end)
or UTF8_ERROR (error)
*/
int
utf8_decode_next(json_utf8_decode *utf8)
{
int c; /* the first byte of the character */
int r; /* the result */
if (utf8->the_index >= utf8->the_length) {
return utf8->the_index == utf8->the_length ? UTF8_END : UTF8_ERROR;
}
utf8->the_byte = utf8->the_index;
utf8->the_char += 1;
c = get(utf8);
/*
Zero continuation (0 to 127)
*/
if ((c & 0x80) == 0) {
return c;
}
/*
One contination (128 to 2047)
*/
if ((c & 0xE0) == 0xC0) {
int c1 = cont(utf8);
if (c1 < 0) {
return UTF8_ERROR;
}
r = ((c & 0x1F) << 6) | c1;
return r >= 128 ? r : UTF8_ERROR;
}
/*
Two continuation (2048 to 55295 and 57344 to 65535)
*/
if ((c & 0xF0) == 0xE0) {
int c1 = cont(utf8);
int c2 = cont(utf8);
if (c1 < 0 || c2 < 0) {
return UTF8_ERROR;
}
r = ((c & 0x0F) << 12) | (c1 << 6) | c2;
return r >= 2048 && (r < 55296 || r > 57343) ? r : UTF8_ERROR;
}
/*
Three continuation (65536 to 1114111)
*/
if ((c & 0xF1) == 0xF0) {
int c1 = cont(utf8);
int c2 = cont(utf8);
int c3 = cont(utf8);
if (c1 < 0 || c2 < 0 || c3 < 0) {
return UTF8_ERROR;
}
r = ((c & 0x0F) << 18) | (c1 << 12) | (c2 << 6) | c3;
return r >= 65536 && r <= 1114111 ? r : UTF8_ERROR;
}
return UTF8_ERROR;
}

18
ext/json/utf8_decode.h

@ -0,0 +1,18 @@
/* utf8_decode.h */
#define UTF8_END -1
#define UTF8_ERROR -2
typedef struct json_utf8_decode
{
int the_index;
char *the_input;
int the_length;
int the_char;
int the_byte;
} json_utf8_decode;
extern int utf8_decode_at_byte(json_utf8_decode *utf8);
extern int utf8_decode_at_character(json_utf8_decode *utf8);
extern void utf8_decode_init(json_utf8_decode *utf8, char p[], int length);
extern int utf8_decode_next(json_utf8_decode *utf8);

56
ext/json/utf8_to_utf16.c

@ -0,0 +1,56 @@
/* utf8_to_utf16.c */
/* 2005-12-25 */
/*
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utf8_to_utf16.h"
#include "utf8_decode.h"
int
utf8_to_utf16(unsigned short w[], char p[], int length)
{
int c;
int the_index = 0;
json_utf8_decode utf8;
utf8_decode_init(&utf8, p, length);
for (;;) {
c = utf8_decode_next(&utf8);
if (c < 0) {
return UTF8_END ? the_index : UTF8_ERROR;
}
if (c < 0x10000) {
w[the_index] = (unsigned short)c;
the_index += 1;
} else {
c &= 0xFFFF;
w[the_index] = (unsigned short)(0xD800 | (c >> 10));
the_index += 1;
w[the_index] = (unsigned short)(0xDC00 | (c & 0x3FF));
the_index += 1;
}
}
}

3
ext/json/utf8_to_utf16.h

@ -0,0 +1,3 @@
/* utf8_to_utf16.h */
extern int utf8_to_utf16(unsigned short w[], char p[], int length);
Loading…
Cancel
Save