From 974bd9d0f9f3d231ff99496c55ae40355398cfc6 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 26 Oct 2014 12:56:28 +1300 Subject: [PATCH] Resolve a quoting ambiguity in nested response specs --- libpathod/language.py | 21 +++++++++++---------- test/test_language.py | 22 +++++++++++++--------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/libpathod/language.py b/libpathod/language.py index d8e871458..42fffcf82 100644 --- a/libpathod/language.py +++ b/libpathod/language.py @@ -1,4 +1,3 @@ -from __future__ import print_function import operator import string import random @@ -15,6 +14,12 @@ import utils BLOCKSIZE = 1024 TRUNCATE = 1024 +def quote(s): + quotechar = s[0] + s = s[1:-1] + s = s.replace(quotechar, "\\" + quotechar) + return quotechar + s + quotechar + class FileAccessDenied(Exception): pass @@ -272,7 +277,7 @@ class ValueLiteral(_ValueLiteral): return e.setParseAction(lambda x: klass(*x)) def spec(self): - return '"%s"'%self.val.encode("string_escape") + return quote("'%s'"%self.val.encode("string_escape")) class ValueNakedLiteral(_ValueLiteral): @@ -551,17 +556,13 @@ class PathodSpec(_Token): self.value.get_generator(settings), ] - def quote(self, s): - quotechar = s[0] - s = s[1:-1] - s = s.replace(quotechar, "\\" + quotechar) - return quotechar + s + quotechar - def spec(self): - return "s%s"%(self.quote(self.value.spec())) + return "s%s"%(self.value.spec()) def freeze(self, settings): - return PathodSpec(ValueLiteral(self.parsed.freeze(settings).spec())) + f = self.parsed.freeze(settings).spec() + print [f] + return PathodSpec(ValueLiteral(f)) class Path(_Component): diff --git a/test/test_language.py b/test/test_language.py index f3cfa5a98..d8392404d 100644 --- a/test/test_language.py +++ b/test/test_language.py @@ -36,10 +36,13 @@ class TestValueLiteral: def test_spec(self): v = language.ValueLiteral("foo") - assert v.spec() == r'"foo"' + assert v.spec() == r"'foo'" v = language.ValueLiteral("f\x00oo") - assert v.spec() == repr(v) == r'"f\x00oo"' + assert v.spec() == repr(v) == r"'f\x00oo'" + + v = language.ValueLiteral("\"") + assert v.spec() == repr(v) == '\'"\'' def test_freeze(self): v = language.ValueLiteral("foo") @@ -186,7 +189,7 @@ class TestMisc: assert e.parseString("'get'")[0].value.val == "get" assert e.parseString("get")[0].spec() == "get" - assert e.parseString("'foo'")[0].spec() == '"foo"' + assert e.parseString("'foo'")[0].spec() == "'foo'" s = e.parseString("get")[0].spec() assert s == e.parseString(s)[0].spec() @@ -238,13 +241,14 @@ class TestMisc: f = v.freeze({}) assert "@1" not in f.spec() - r = parse_request('GET:"/foo":s"200"') - assert "200" in r.preamble({}) - - f = r.freeze({}) - assert parse_request(f.spec()) - + def test_pathodspec_freeze(self): + spec = r'GET:"/foo":s"200:ir,\'\"\'"' + r = parse_request(spec) + assert r.freeze({}) + spec = r'GET:"/foo":s"200:ir,\"\'\""' + r = parse_request(spec) + assert r.freeze({}) def test_code(self): e = language.Code.expr()