]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: raise an exception if the struct package is affected by issue #304
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 16 May 2022 00:14:56 +0000 (02:14 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 16 May 2022 01:19:16 +0000 (03:19 +0200)
Cowardly refuse to transform ones in zeros.

psycopg/psycopg/_struct.py
tests/types/test_numeric.py

index ba51164a4c2c628df558cedb5ab487469dea00b1..d6c603cb616bfd44d9f7b2aad905083fbe8d0c1d 100644 (file)
@@ -8,6 +8,7 @@ import struct
 from typing import Callable, cast, Optional, Tuple
 
 from .abc import Buffer
+from . import errors as e
 from ._compat import Protocol, TypeAlias
 
 PackInt: TypeAlias = Callable[[int], bytes]
@@ -40,3 +41,15 @@ unpack_float8 = cast(UnpackFloat, struct.Struct("!d").unpack)
 _struct_len = struct.Struct("!i")
 pack_len = cast(Callable[[int], bytes], _struct_len.pack)
 unpack_len = cast(UnpackLen, _struct_len.unpack_from)
+
+
+def pack_float4_bug_304(x: float) -> bytes:
+    raise e.InterfaceError(
+        "cannot dump Float4: Python affected by bug #304,"
+        " see https://github.com/psycopg/psycopg/issues/304"
+    )
+
+
+# If issue #304 is detected, raise an error instead of dumping wrong data.
+if struct.Struct("!f").pack(1.0) != bytes.fromhex("3f800000"):
+    pack_float4 = pack_float4_bug_304
index e75a43dae534f0a098ea22d2c581360b0174fcd2..8f3ac6ac36a1cbbe1456e889877977c4dd692dbd 100644 (file)
@@ -569,6 +569,18 @@ def test_minus_minus_quote(conn, pgtype):
     assert result == 1
 
 
+@pytest.mark.parametrize("wrapper", "Int2 Int4 Int8 Oid Float4 Float8".split())
+@pytest.mark.parametrize("fmt_in", PyFormat)
+def test_dump_wrapper(conn, wrapper, fmt_in):
+    wrapper = getattr(psycopg.types.numeric, wrapper)
+    obj = wrapper(1)
+    cur = conn.execute(
+        f"select %(obj){fmt_in.value} = 1, %(obj){fmt_in.value}", {"obj": obj}
+    )
+    rec = cur.fetchone()
+    assert rec[0], rec[1]
+
+
 @pytest.mark.parametrize("wrapper", "Int2 Int4 Int8 Oid Float4 Float8".split())
 def test_dump_wrapper_oid(wrapper):
     wrapper = getattr(psycopg.types.numeric, wrapper)