def test_quote_stable_despite_deranged_libpq(conn): # Verify the libpq behaviour of PQescapeString using the last setting seen. # Check that we are not affected by it. good_str = " E'\\\\'" good_bytes = " E'\\\\000'" conn.execute("set standard_conforming_strings to on") assert pq.Escaping().escape_string(b"\\") == b"\\" assert sql.quote("\\") == good_str assert pq.Escaping().escape_bytea(b"\x00") == b"\\000" assert sql.quote(b"\x00") == good_bytes conn.execute("set standard_conforming_strings to off") assert pq.Escaping().escape_string(b"\\") == b"\\\\" assert sql.quote("\\") == good_str assert pq.Escaping().escape_bytea(b"\x00") == b"\\\\000" assert sql.quote(b"\x00") == good_bytes # Verify that the good values are actually good messages = [] conn.add_notice_handler(lambda msg: messages.append(msg.message_primary)) conn.execute("set escape_string_warning to on") for scs in ("on", "off"): conn.execute(f"set standard_conforming_strings to {scs}") cur = conn.execute(f"select {good_str}, {good_bytes}::bytea") assert cur.fetchone() == ("\\", b"\x00") # No "nonstandard use of \\ in a string literal" warning assert not messages
def test_escape_identifier_noconn(pgconn): esc = pq.Escaping() with pytest.raises(psycopg.OperationalError): esc.escape_identifier(b"hi") esc = pq.Escaping(pgconn) pgconn.finish() with pytest.raises(psycopg.OperationalError): esc.escape_identifier(b"hi")
def test_escape_string_badenc(pgconn): res = pgconn.exec_(b"set client_encoding to 'UTF8'") assert res.status == pq.ExecStatus.COMMAND_OK data = "\u20ac".encode("utf8")[:-1] esc = pq.Escaping(pgconn) with pytest.raises(psycopg.OperationalError): esc.escape_string(data)
def test_escape_string_noconn(data, want): esc = pq.Escaping() out = esc.escape_string(data) if isinstance(want, bytes): assert out == want else: assert out in want
def test_escape_noconn(pgconn): data = bytes(range(256)) esc = pq.Escaping() escdata = esc.escape_bytea(data) res = pgconn.exec_params(b"select '%s'::bytea" % escdata, [], result_format=1) assert res.status == pq.ExecStatus.TUPLES_OK assert res.get_value(0, 0) == data
def test_unescape_bytea(pgconn, data): enc = br"\x" + b"".join(b"%02x" % c for c in data) esc = pq.Escaping(pgconn) rv = esc.unescape_bytea(enc) assert rv == data pgconn.finish() with pytest.raises(psycopg.OperationalError): esc.unescape_bytea(data)
def test_escape_identifier_1char(pgconn, scs): res = pgconn.exec_( f"set standard_conforming_strings to {scs}".encode("ascii")) assert res.status == pq.ExecStatus.COMMAND_OK esc = pq.Escaping(pgconn) special = {b'"': b'""""', b"\\": b'"\\"'} for c in range(1, 128): data = bytes([c]) rv = esc.escape_identifier(data) exp = special.get(data) or b'"%s"' % data assert rv == exp
def test_escape_literal_1char(pgconn, scs): res = pgconn.exec_( f"set standard_conforming_strings to {scs}".encode("ascii")) assert res.status == pq.ExecStatus.COMMAND_OK esc = pq.Escaping(pgconn) special = {b"'": b"''''", b"\\": b" E'\\\\'"} for c in range(1, 128): data = bytes([c]) rv = esc.escape_literal(data) exp = special.get(data) or b"'%s'" % data assert rv == exp
def test_escape_string_1char(pgconn, scs): esc = pq.Escaping(pgconn) res = pgconn.exec_( f"set standard_conforming_strings to {scs}".encode("ascii")) assert res.status == pq.ExecStatus.COMMAND_OK special = {b"'": b"''", b"\\": b"\\" if scs == "on" else b"\\\\"} for c in range(1, 128): data = bytes([c]) rv = esc.escape_string(data) exp = special.get(data) or b"%s" % data assert rv == exp
def test_escape_string(pgconn, data, want): esc = pq.Escaping(pgconn) out = esc.escape_string(data) assert out == want
def test_escape_identifier(pgconn, data, want): esc = pq.Escaping(pgconn) out = esc.escape_identifier(data) assert out == want
def test_escape_1char(pgconn): esc = pq.Escaping(pgconn) for c in range(256): rv = esc.escape_bytea(bytes([c])) exp = br"\x%02x" % c assert rv == exp
def test_escape_string_badconn(pgconn): esc = pq.Escaping(pgconn) pgconn.finish() with pytest.raises(psycopg.OperationalError): esc.escape_string(b"hi")
def quote(self, obj: str) -> bytes: value = self.dump(obj) esc = pq.Escaping() return b"'%s'" % esc.escape_string(value.replace(b"h", b"q"))