You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
json_tree: a stored float can come back one ulp off because numbers are re-parsed without serde_json float_roundtrip #1364
EQL v4's json_tree is the encrypted JSON column type that Stack Encrypt (the Rust crate stack-encrypt) writes: one encrypted entry per JSON node, so PostgreSQL can search the document without the key. When a document is sealed, each number leaf is written into its entry's ciphertext as text (serde_json::Number::to_string, in encode_node in packages/stack-encrypt/src/json/derive.rs). When the client opens the entry, the text is parsed back into a serde_json::Number.
Problem
serde_json is built without its float_roundtrip feature. Without it, parsing a float uses a fast path that is not guaranteed to return the nearest f64, so a value can come back one unit in the last place away from the one that was stored. A property test over random f64 values found a concrete case while PR #1363 was being written: -926809.5051008083 was stored and -926809.5051008085 came back.
Who hits it: any application that stores a float with a full-precision decimal expansion in a json_tree column and reads it back through a subtree read or ->. The value is silently wrong in the last digit; nothing errors. Integers and floats with short decimal expansions are unaffected. Nothing catches it today because the existing tests use exactly representable floats, and the property test in #1363 was narrowed to them so it would pass.
Proposal
Enable serde_json's float_roundtrip feature in packages/stack-encrypt/Cargo.toml (and check the other crates that parse the same text: eql-bindings, the Go and WASM guests if they re-parse numbers).
Widen the property test in packages/stack-encrypt/tests/json_properties.rs back to arbitrary finite f64 values, so the test fails if the feature is ever dropped.
Check whether the ordering term and the value selector derive from the parsed value anywhere on the read side; if they do, they are affected the same way.
Relationship to other work
Found while implementing #1360 in PR #1363, which does not fix it. Refs #1363.
Activity
coderdan commentedon Oct 25, 2026
Fixed in draft PR #1366 (serde_json
float_roundtripon stack-encrypt, with a regression test and a property test over arbitrary finite f64). https://claude.ai/code/session_01N7bCqa3ZVJMcEE99RzVqEu