in reply to Re^2: JSON::XS and escaping literal strings
in thread JSON::XS and escaping literal strings

This works though, right?

(my $json = JSON->new->encode(\%data)) =~ s{\/}{\\\/}g;

Replies are listed 'Best First'.
Re^4: JSON::XS and escaping literal strings
by Anonymous Monk on Jun 07, 2018 at 21:27 UTC

    Yes, it does.

    I did some more research on this. I confirmed that the JSON spec does not require escaping of forward slashes.

    Some platforms escape the forward slash by default but allow you to disable that behavior (e.g., php, json-c). I assume that's for safety.

    Others expect you to escape it yourself when using it within the context of HTML. Ruby's ERB provides an escape_json method. Here's the essence of that:

    JSON_ESCAPE = { "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u +2028" => '\u2028', "\u2029" => '\u2029' } JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u

    I've decided to move to Cpanel::JSON::XS, since it has support for more of the ::PP settings. And I've written a wrapper around it for our app that sets the appropriate defaults (e.g., escape_slash). I wrote a Perl version of the escape_json() from ERB.

    { my %escape = ( "&" => '\u0026', ">" => '\u003E', "<" => '\u003C', '\x{2028}' => '\u2028', '\x{2029}' => '\u2029', ); my $chars = join '', keys %escape; my $regex = qr/[$chars]/; sub escape_for_html { my $class = shift; @_ or croak 'no json supplied'; my @json = @_; foreach (@json) { s/($regex)/$escape{ $1 }/ge if defined; } return wantarray ? @json : join('', @json); } }

      sub escape_for_html { @_ or croak 'no json supplied';

      Um, no. escaping for html isn't json specific, even if you're using it for json.

      See also HTML::Entities

        The idea of escaping things for HTML isn't specific to JSON, but this particular mechanism of escaping is.

        Firstly, in typical HTML, a slash is a safe character which won't need escaping. You'd normally need to escape "<" and "&" characters (and quotes if you're outputting data within an attribute), though often ">" is escaped for symmetry. However, as you're outputting the JSON within a <script> element, the usual escaping isn't necessary and (unless you're serving your HTML as XHTML with an XML media type) will not work. HTML::Entities will not work for this purpose. However, the combination of "</" is still dangerous so needs escaping. Escaping "/" as "\/" is specific to Javascript/JSON strings, not a general HTML thing.

        Well, no, you can't simply HTML encode it. If you want to display JSON within an HTML document, then sure. But the goal here is to safely embed the JSON within a script tag.

        We can quibble about the naming, but the point is that the forward slash needs to be escaped in this context because it is being placed within the script tag. It has nothing to do with JSON per se.