Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Flask checking `'\\/' in json.dumps('/')` in its json module?

Tags:

python

flask

The source for the flask.json module contains the following line. What does '\\/' mean, and why is Flask checking this?

_slash_escape = '\\/' not in _json.dumps('/')
like image 545
Rolex Avatar asked Aug 07 '15 17:08

Rolex


People also ask

What is the difference between json loads and dumps?

loads() takes in a string and returns a json object. json. dumps() takes in a json object and returns a string.

Why we use json dumps in Python?

The dump() method is used when the Python objects have to be stored in a file. The dumps() is used when the objects are required to be in string format and is used for parsing, printing, etc, . The dump() needs the json file name in which the output has to be stored as an argument.

What is json dumps and json loads in Python?

json loads -> returns an object from a string representing a json object. json dumps -> returns a string representing a json object from an object. load and dump -> read/write from/to file instead of string.

How does json dump work?

json. dumps() function will convert a subset of Python objects into a json string. Not all objects are convertible and you may need to create a dictionary of data you wish to expose before serializing to JSON.


2 Answers

Flask is using this to test if the JSON library it's using escapes slashes when it doesn't have to. If the library does, then json.dump('/') will produce '"\\/"' (equivalent to the raw string r'"\/"', see here for an explanation on escape characters).

Flask can choose one of multiple JSON libraries, and some libraries/versions escape forward slashes while others don't. Flask includes a comment explaining this.

If the library does escape slashes, Flask will undo this when it dumps the JSON, for consistency between libraries.

# figure out if simplejson escapes slashes.  This behavior was changed
# from one version to another without reason.
_slash_escape = '\\/' not in _json.dumps('/')
...
def htmlsafe_dumps(obj, **kwargs):
    ...
    if not _slash_escape:
        rv = rv.replace('\\/', '/')
    ...

Flask still escapes unsafe HTML characters when rendering the JSON in HTML, so the potentially unsafe string "</script>" becomes "\\u003c/script\\u003e" which is safe.

like image 69
davidism Avatar answered Nov 04 '22 05:11

davidism


Backslash (\) is the escape character. In several programming languages, it means to treat the next character as a literal whatever, instead of letting it perform its normal function (example: put a literal quote instead of treating it as an end quote).

Two backslashes (\\) means a literal backslash. As in, don't perform the escaping function.

So an escaped slash in JSON is \/, but to detect that Python has to use \\/ or else it will treat the backslash as an escape.

As an aside, this is why Python offers so-called "raw string literals" prefixed by r'', so that you don't have to write \\ to get a literal backslash.

Credit to davidism for discovering the specific reason Flask does this before I could. See this answer explaining that in more detail.

like image 26
Two-Bit Alchemist Avatar answered Nov 04 '22 05:11

Two-Bit Alchemist