

WebKit breaks with other browsers and treats RegExps as functions in native JSON - ls_n
https://bugs.webkit.org/show_bug.cgi?id=28117

======
ars
Your title is not what the bug report says.

The problem is that functions should not go in json (when you create json),
but regex's are sort of functions, so the question is if they should go in the
json anyway. The question is not if they should be treated as functions.

~~~
gjm11
That was the original issue, but then an argument about regexps arose in the
comments. The situation appears to be as follows.

1\. For JSON serialization, (non-callable) objects are meant to be serialized
(but, IIUC, in a way that would lose all the useful information in a regexp
object) whereas functions -- more precisely, callable things -- are meant not
to be (so if an object has a property whose value is a function, it should
simply be omitted on serialization, and if an array contains a function, it
should be replaced with null on serialization).

2\. The original bug: WebKit serializes callable things the same way as
uncallable ones. Everyone agrees that that's a bug, and the WebKit people have
fixed it.

3\. The JS spec doesn't say whether or not regexp objects are callable
(equivalently, whether typeof returns "function" for them).

4\. Most browsers make regexps callable. Some don't (all IE versions and
Chrome up to version 2).

5\. WebKit has callable regexps and accordingly doesn't (now) serialize them.

6\. Firefox has callable regexps but does serialize them.

7\. Nothing serializes regexps in any way that's of actual use. Firefox
produces {}. WebKit doesn't serialize them.

~~~
gjm11
Oh, and: The JS spec defines callability indirectly. There's this notion of
"internal properties" (i.e., fictional properties that some objects have and
some lack) and "abstract operations" (i.e., fictional functions defined on JS
objects) and the spec often says things like "Such-and-such a function tests
for internal property [[Foo]] and then invokes abstract operation _Bar_ ".

So, what happens when you say "f()" in JavaScript? It's defined in terms of an
abstract operation called _IsCallable_ and an internal property called
[[Call]]. _IsCallable_ , in turn, is defined as "has the [[Call]] internal
property". The spec specifies, e.g., that when you define a function the
resulting object has [[Call]], and that numbers don't have [[Call]].

But it never says any of the following: (1) "RegExp objects have [[Call]]".
(2) "Regexp objects do not have [[Call]]". (3) "Nothing has [[Call]] unless
this spec says it does". (4) "When this spec doesn't say whether an object has
[[Call]], it's up to each implementation whether it does." For some other
internal properties there _is_ a clause like (3), but not for [[Call]].

Which means that it's debatable whether making regexps callable is permitted
by the spec (I think it is), but (I think) it's clear that _if_ regexps are
callable _then_ they must be treated as having [[Call]], which means that they
should not be serialized. But I am not a JS expert, and you should take the
above with a grain of salt.

~~~
ars
That's a good summary.

IMO just because a regex is callable does not mean it should be omitted
(despite the spec). If it can be serialized in a proper way then go ahead. (I
know it has other properties, but just emitting /foo/ would be fine with me.)

A RegExp is probably a special case. The browsers should do the useful thing,
and request an errata on the spec.

Wait, are they talking about the global RegExp object, or a specific RegExp?

And they should fork this bug into one just about RegExp.

~~~
gjm11
Serializing a regexp as, say, "/foo/" would mean emitting alleged JSON that
doesn't conform to the JSON grammar in the spec, and that existing JSON
parsers might be completely unable to do anything with. It might make some
sense to change the spec to include regexp literals, but while the spec says
what it does it would be unresponsible for any browser's _stringify_
implementation to emit things that others' _parse_ implementations might barf
on.

(It's a pity that JSON isn't more easily extensible in a backward-compatible
manner. On the other hand, it's not clear how that could have been enabled
without breaking the it's-just-a-subset-of-JS-literal-syntax principle.)

