Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-14 Thread Rasmus Lerdorf
mike wrote:
 On Sun, Dec 14, 2008 at 12:39 AM, Rasmus Lerdorf ras...@lerdorf.com wrote:
 
 Eh?  Read what you wrote there.  If json wasn't pure javascript, how in
 the world would eval() work on it?
 
 Sorry. I guess I meant it didn't execute by itself, but needed to be
 interpreted using something like eval and/or thrown into a variable
 before it was useful. Otherwise it's just text.
 
 I'm not sure why we had to do that workaround I previously mentioned,
 and I cannot find a repository with that old code, but nowadays
 json_encode seems to work seamlessly for all the data we exchange
 (which are strings, ints, arrays, no objects, possibly not even
 booleans) and just wanted to voice off if there was any possible
 incompatibility that may be introduced here.
 
 I'll go back in my corner now :)

I thought I explained that a few times now.  JSON is defined in the RFC
as a subset of Javascript, so a JSON Parser doesn't need to have all
the capabilities of the javascript parser.  Things break if you pass the
output of json_encode() to a JSON parser that follows the RFC to the letter.

When we do json_encode(123) we spit out just: 123
or json_encode(abc) we produce just: abc

this is obviously valid Javascript so both eval and direct injection
into a script block (which is the same thing) will work fine.  But the
RFC says we should be wrapping either array or object notation around
it.  As in [123] and [abc] to make it valid JSON.  Direct injection
into scriptvar foo = ?php echo json_encode(abc)?;/script will
still work, of course, the only change is that foo now becomes an array
with a single string element as opposed to just the string itself, so
making this change will break existing javascript that relies on PHP
producing unwrapped basic types.

Now, in most cases when you are passing stuff around via json, you don't
do that for a single value, so in most cases you end up passing an array
anyway, and in that case nothing changes.

-Rasmus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] Removing basic types from our JSON parser

2008-12-14 Thread Uwe Schindler
 script
 var foo = ?php echo json_encode($foo)?;
 /script
 
 will always work.  The only question is what sort of variable foo will
 end up being.  The RFC says we have to wrap basic types in an array or
 object, while currently we let the basic types through without the
 wrapper.

He problem her eis: A lot of people use in a way and assume, that a basic
type is serialized as a basic type in JSON/JS. If we change this, it could
break a lot of apps.

And the above is really nice to encode PHP strings to a secure JS variant.
It is hard to do with addslashes etc. So I think, we should not change the
way it works currently.

I think in the docs for json_encode() should be a warning: JSON officially
only supports Objects and Arrays as outer/top-level/... type for JSON
serializations. So the argument of json_encode must be a PHP object or array
to be fully JSON conformant. If you provide a simple type (string, number,
Boolean), json_encode will generate a valid java script, but some conformant
JSON parser may not be able to read it. How about this?

Uwe


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-14 Thread David Grudl

 Původní zpráva 
Předmět: [PHP-DEV] Removing basic types from our JSON parser
Od: theta...@php.net (Uwe Schindler)
Komu:
Datum: 14.12.2008 10:40


script
var foo = ?php echo json_encode($foo)?;
/script

will always work.  The only question is what sort of variable foo will
end up being.  The RFC says we have to wrap basic types in an array or
object, while currently we let the basic types through without the
wrapper.


He problem her eis: A lot of people use in a way and assume, that a basic
type is serialized as a basic type in JSON/JS. If we change this, it could
break a lot of apps.


+1

In PHP there is no function for escaping JS strings and json_encode is 
useful compensation. I use it this way very often.



David Grudl

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread Uwe Schindler
 For reference I saw people use json_encode() to pass a string to
 javascript into their page while avoiding bugs/XSS with stuff like
 /script.
 
 var foo = ?=json_encode($my_string)?;
 ... (yes, they maybe heared somewhere that JSON is *not* javascript, I
 told 'em too).

This is not correct. JSON *is* valid JavaScript, but the other way round is
not correct. Not every Javascript is JSON. So it is perfectly legal, to do
this.

I think, this is really cool, using json_encode() as something like
htmlspecialchars for correctly encoding strings inside JS for security. I
use it, too.

To the problem with basic types: I like the way of maybe giving a option to
the function. If you want to be standards conformant, you have to remove the
encoding parameter (which is also there), too. JSON has to be UTF-8, if you
want to be conform to the specs. But for the example above (secure encoding
of JS strings with json_encode), it is perfectly legal to use another
encoding (in the above case, the encoding of the HTML page).

Uwe


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread Stan Vassilev | FM

var foo = ?=json_encode($my_string)?;
... (yes, they maybe heared somewhere that JSON is *not* javascript, I
told 'em too).


JSON is a strict subset of JavaScript, and the above scenario is something I 
also do often.


Since PHP generates web pages, any time I need to generate a JS literal 
json_encode() is the natural equivalent of var_export(.., true) for PHP 
literals.


Since it may not match the RFC apparently, I suggest a flag as some other 
people said:


function json_encode($var, $allowScalar = false) {}

This way we gain best of both worlds without disrupting either specs nor 
existing workflows.


Regards,
Stan Vassilev 



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread Rasmus Lerdorf
Stan Vassilev | FM wrote:
 var foo = ?=json_encode($my_string)?;
 ... (yes, they maybe heared somewhere that JSON is *not* javascript, I
 told 'em too).
 
 JSON is a strict subset of JavaScript, and the above scenario is
 something I also do often.
 
 Since PHP generates web pages, any time I need to generate a JS literal
 json_encode() is the natural equivalent of var_export(.., true) for PHP
 literals.
 
 Since it may not match the RFC apparently, I suggest a flag as some
 other people said:
 
 function json_encode($var, $allowScalar = false) {}

I'm not sure if that is the right way of looking at it though.  I think
the only question is how to represent the scalar types, not whether they
should be allowed.  As far as I am concerned it is obvious that they be
allowed and the JSON spec is quite explicit that JSON can be used to
represent scalar types:

   JSON can represent four primitive types (strings, numbers,
   booleans, and null) and two structured types (objects and arrays).

The only question is how to serialize these into a JSON-text string.
Again, from the RFC:

   A JSON text is a sequence of tokens.  The set of tokens includes six
   structural characters, strings, numbers, and three literal names.

   A JSON text is a serialized object or array.

This last statement is the issue.  When serializing a basic type into a
JSON text string, the RFC says we need to wrap it inside an array or
object.  So, if we are going to add an option to json_encode(), that's
what the option should do.  Specify whether, and perhaps how, to wrap
basic types, not whether to allow or disallow them.

I'll talk to Douglas on Monday if he is in the office and get his opinion.

-Rasmus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread moo . tinys

 I'm not sure if that is the right way of looking at it though.  I think
 the only question is how to represent the scalar types, not whether they
 should be allowed.  As far as I am concerned it is obvious that they be
 allowed and the JSON spec is quite explicit that JSON can be used to
 represent scalar types:

   JSON can represent four primitive types (strings, numbers,
   booleans, and null) and two structured types (objects and arrays).

 The only question is how to serialize these into a JSON-text string.
 Again, from the RFC:

   A JSON text is a sequence of tokens.  The set of tokens includes six
   structural characters, strings, numbers, and three literal names.

   A JSON text is a serialized object or array.

 This last statement is the issue.  When serializing a basic type into a
 JSON text string, the RFC says we need to wrap it inside an array or
 object.  So, if we are going to add an option to json_encode(), that's
 what the option should do.  Specify whether, and perhaps how, to wrap
 basic types, not whether to allow or disallow them.

 I'll talk to Douglas on Monday if he is in the office and get his opinion.

 -Rasmus
cool.
let's see how :D. Crockford explain it :D
but before he can react on this thread, i guess Rasmus is right
understanding the RFC.
json force your encoder to output the following in encoded form
 1. array: multiple of unnamed values
 2. object: multiple of named values
so it's right to wrap it in object or array (u can say remove basic types)

json_encode(array(1)); = [1]
json_encode(array(1, 2, 3, 1)); = [1,2,3,1]

json_encode(array('value1' = 1)); = {value1:1}
json_encode(array('a'=1, 'b'=2, 'c'=3, 'd'=1)); = {a:1,
b:2,c:3,d:1}

i'd prefer 2 new functions: js_encode (or js_export?) js_decode which
support basic types instead of having an extra optional parameter

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread mike
Sorry for top posting. I see no reason why php should not interop with  
javascript 100% as it should. I do not see a reason to create new  
functions, parameters, etc. The existing should be expected to both  
encode and decode json with javascript properly. If there is a  
mismatch right now, then it should be fixed.


On Dec 13, 2008, at 10:10 PM, moo.tinys moo.ti...@gmail.com wrote:



I'm not sure if that is the right way of looking at it though.  I  
think
the only question is how to represent the scalar types, not whether  
they
should be allowed.  As far as I am concerned it is obvious that  
they be

allowed and the JSON spec is quite explicit that JSON can be used to
represent scalar types:

 JSON can represent four primitive types (strings, numbers,
 booleans, and null) and two structured types (objects and arrays).

The only question is how to serialize these into a JSON-text string.
Again, from the RFC:

 A JSON text is a sequence of tokens.  The set of tokens includes six
 structural characters, strings, numbers, and three literal names.

 A JSON text is a serialized object or array.

This last statement is the issue.  When serializing a basic type  
into a

JSON text string, the RFC says we need to wrap it inside an array or
object.  So, if we are going to add an option to json_encode(),  
that's

what the option should do.  Specify whether, and perhaps how, to wrap
basic types, not whether to allow or disallow them.

I'll talk to Douglas on Monday if he is in the office and get his  
opinion.


-Rasmus

cool.
let's see how :D. Crockford explain it :D
but before he can react on this thread, i guess Rasmus is right
understanding the RFC.
json force your encoder to output the following in encoded form
1. array: multiple of unnamed values
2. object: multiple of named values
so it's right to wrap it in object or array (u can say remove  
basic types)


json_encode(array(1)); = [1]
json_encode(array(1, 2, 3, 1)); = [1,2,3,1]

json_encode(array('value1' = 1)); = {value1:1}
json_encode(array('a'=1, 'b'=2, 'c'=3, 'd'=1)); = {a:1,
b:2,c:3,d:1}

i'd prefer 2 new functions: js_encode (or js_export?) js_decode which
support basic types instead of having an extra optional parameter

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread Rasmus Lerdorf
mike wrote:
 Sorry for top posting. I see no reason why php should not interop with
 javascript 100% as it should. I do not see a reason to create new
 functions, parameters, etc. The existing should be expected to both
 encode and decode json with javascript properly. If there is a mismatch
 right now, then it should be fixed.

There is no mismatch with Javascript now at all.  We spit out perfectly
valid Javascript.  There is only a slight mismatch with the JSON RFC
which defines a stricter subset of Javascript than we are using.

-Rasmus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread mike
I can't give specifics (I'm mobile and I don't remember where the code  
would be anyway) but we had an issue with php and javascript exchange  
via json where the php output using json_encode and we had to wrap it  
with additional braces for it to be usable. Sorry for being vague,  
this thread reminded me of that which is why I wanted to voice off.


Thanks for the clarification (and thank you so much for PHP :))

On Dec 13, 2008, at 10:39 PM, Rasmus Lerdorf ras...@lerdorf.com wrote:


mike wrote:
Sorry for top posting. I see no reason why php should not interop  
with

javascript 100% as it should. I do not see a reason to create new
functions, parameters, etc. The existing should be expected to both
encode and decode json with javascript properly. If there is a  
mismatch

right now, then it should be fixed.


There is no mismatch with Javascript now at all.  We spit out  
perfectly

valid Javascript.  There is only a slight mismatch with the JSON RFC
which defines a stricter subset of Javascript than we are using.

-Rasmus


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-13 Thread Rasmus Lerdorf
Yes, but that would be going to a json_parse thing somewhere, not pure
Javascript.

-Rasmus

mike wrote:
 I can't give specifics (I'm mobile and I don't remember where the code
 would be anyway) but we had an issue with php and javascript exchange
 via json where the php output using json_encode and we had to wrap it
 with additional braces for it to be usable. Sorry for being vague, this
 thread reminded me of that which is why I wanted to voice off.
 
 Thanks for the clarification (and thank you so much for PHP :))
 
 On Dec 13, 2008, at 10:39 PM, Rasmus Lerdorf ras...@lerdorf.com wrote:
 
 mike wrote:
 Sorry for top posting. I see no reason why php should not interop with
 javascript 100% as it should. I do not see a reason to create new
 functions, parameters, etc. The existing should be expected to both
 encode and decode json with javascript properly. If there is a mismatch
 right now, then it should be fixed.

 There is no mismatch with Javascript now at all.  We spit out perfectly
 valid Javascript.  There is only a slight mismatch with the JSON RFC
 which defines a stricter subset of Javascript than we are using.

 -Rasmus


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-12 Thread mike
 Fri, Dec 12, 2008 at 7:50 PM, Scott MacVicar sc...@macvicar.net wrote:

 The problem here is that none of the other JSON parsers in any other
 language support this and more importantly the browsers [2] which are now
 adding native JSON support. Users are frequently expecting the result from a
 json_encode in PHP to just work with JSON.parse() on the client side. [3]

 I have a patch for this that implements the RFC exactly and makes secure
 json_encode only works with objects and arrays.

definately +1

we use json both encoding and decoding to interact with javascript and
ensuring that PHP's built-in json is standards compliant is an
absolute must. -please- make sure it works both encoding php - js,
decoding js - php for all relevant types in both languages. thank you
:)

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-12 Thread Mark Karpeles
Le samedi 13 décembre 2008 à 03:50 +, Scott MacVicar a écrit :
 Hi All,
 
 Basic types were added to our JSON decoder to PHP 5.2.1, this allows  
 one to use json_encode / json_decode on any of our scalar types. Omar  
 correctly identified #38680 as not a bug but it appears that Ilia  
 added support for this anyway violating the RFC [1]. Maybe there was a  
 reason for this but I'm not sure why?

The reason was to make json_decode() able to decode anything encoded by
json_encode(). I believe many people may be depending on this (I saw a
few codes).

If json_decode() is made to only accept arrays/struct, the same should
be done to json_encode().

For reference I saw people use json_encode() to pass a string to
javascript into their page while avoiding bugs/XSS with stuff like
/script.

var foo = ?=json_encode($my_string)?;
... (yes, they maybe heared somewhere that JSON is *not* javascript, I
told 'em too).

I also saw people using json_encode/json_decode as an alternate for
serialize/unserialize.

Also, reading [2], I see about stringify If value is an object or
array, the structure will be visited recursively to determine the
serialization of each membr or element., this seems to assume that
value can be something else than an object or array.

At least on Firefox 3.2, it is not the case.

 The problem here is that none of the other JSON parsers in any other  
 language support this and more importantly the browsers [2] which are  
 now adding native JSON support. Users are frequently expecting the  
 result from a json_encode in PHP to just work with JSON.parse() on the  
 client side. [3]

I did some tests with firefox minefield (3.2pre) :


javascript:alert(JSON.stringify({foo: bar}));
 = {foo:bar}

javascript:alert(JSON.stringify(true));
 = Invalid argument

javascript:alert(JSON.stringify(hello world));
 = Invalid argument

javascript:alert(JSON.stringify([hello world]));
 = [hello world]

javascript:alert(JSON.parse([\hello world\]));
 = hello world
(bug? or alert() behaviour when receiving an array?)

javascript:alert(JSON.parse(\hello world\));
 = Error parsing JSON

javascript:alert(JSON.parse(null));
 = Error parsing JSON

 I have a patch for this that implements the RFC exactly and makes  
 secure json_encode only works with objects and arrays.
 
 This would be a change for 5.3+ and we should just document in 5.2  
 that what we did was a bad idea.

I'm +0 on this, because it will break PHP code on one side, but will
break on browser stuff on the other side.

I guess making 5.3 throwing E_WARNING (or E_DEPRECATED, if someone reads
it) and removing this support in HEAD could be the default behaviour
based on how we handled most features we wanted to remove when people
started relying on those.

Anyway, maintaining two versions of the JSON parser is not something we
want (I believe) so this should be removed as soon as possible. I'm just
not sure about breaking this features this fast.


Mark

 [1] - http://www.ietf.org/rfc/rfc4627.txt?number=4627
 [2] - http://wiki.ecmascript.org/doku.php?id=es3.1:json_support
 [3] - https://developer.mozilla.org/en/Using_JSON_in_Firefox
 


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Removing basic types from our JSON parser

2008-12-12 Thread Rasmus Lerdorf
Mark Karpeles wrote:
 Le samedi 13 décembre 2008 à 03:50 +, Scott MacVicar a écrit :
 Hi All,

 Basic types were added to our JSON decoder to PHP 5.2.1, this allows  
 one to use json_encode / json_decode on any of our scalar types. Omar  
 correctly identified #38680 as not a bug but it appears that Ilia  
 added support for this anyway violating the RFC [1]. Maybe there was a  
 reason for this but I'm not sure why?
 
 The reason was to make json_decode() able to decode anything encoded by
 json_encode(). I believe many people may be depending on this (I saw a
 few codes).
 
 If json_decode() is made to only accept arrays/struct, the same should
 be done to json_encode().
 
 For reference I saw people use json_encode() to pass a string to
 javascript into their page while avoiding bugs/XSS with stuff like
 /script.
 
 var foo = ?=json_encode($my_string)?;
 ... (yes, they maybe heared somewhere that JSON is *not* javascript, I
 told 'em too).
 
 I also saw people using json_encode/json_decode as an alternate for
 serialize/unserialize.
 
 Also, reading [2], I see about stringify If value is an object or
 array, the structure will be visited recursively to determine the
 serialization of each membr or element., this seems to assume that
 value can be something else than an object or array.
 
 At least on Firefox 3.2, it is not the case.

I think it does more than assume that.  The spec specifically says that
the value can be any Javascript value in the prototype:

 JSON.stringify(value, replacer, space)

  value   any JavaScript value, usually an object or array.

  replaceran optional parameter that determines how object
  values are stringified for objects without a toJSON
  method. It can be a function or an array.

  space   an optional parameter that specifies the indentation
  of nested structures. If it is omitted, the text will
  be packed without extra whitespace. If it is a number,
  it will specify the number of spaces to indent at each
  level. If it is a string (such as '\t' or 'nbsp;'),
  it contains the characters used to indent at each level.

I think we should follow the spec, not individual browser implementations.

-Rasmus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php