ata-validator
1.61.3 · 29 Oct 2026MIT21.8k / weekRepositoryHomepagenpmAtom feed
1.61.3 is the newest release of 1.x.
In short
1 fixed1 changed
Release note
Fixed
validate()read past the end of the document the caller handed it. simdjson wants padding after a document so its SIMD loads can run off the end, and the library was claiming that padding on buffers it does not own, on the grounds that a buffer not ending near a page boundary has readable bytes after it. That does not fault, which is why it went unnoticed, but the bytes belong to somebody else: under AddressSanitizer it reports as a heap-buffer-overflow inside simdjson, so anyone fuzzing or sanitizing an application built on ata saw a memory error with no way to tell it was deliberate. Through the Node binding the read landed in V8's heap. The document is now copied into a padded buffer, reused per thread, before it is parsed. The buffer APIs already did this and were never affected. Found by the fuzz targets infuzz/, which were in the repository but had never been run; all three now survive millions of executions clean.
Changed
Rejecting a document through the buffer APIs no longer costs more than accepting one. The On-Demand plan answers first, and a
falsefrom it used to be ambiguous: it could mean the document failed a constraint, or that the plan could not decide. The caller had to assume the second, so it re-created the padded view, parsed the whole document again into a DOM, tried the generated plan, and then walked the tree. A rejected document was therefore parsed twice and walked up to three times. The plan now reports whether it stopped because the document failed a constraint or because it could not be read, and only the second falls through. simdjson'sINCORRECT_TYPEis a constraint failure rather than a read failure, which is the distinction that makes this work: a property holding a string where the schema wants an integer surfaces as a read error fromget<int64>, not as a type mismatch. On a 62 KB array of a thousand objects with one bad element: 316 µs to 11 µs when the bad element is first, 315 µs to 40 µs when it is last, and rejecting is now never dearer than accepting.tests/test_buffer_path_parity.jsholds the buffer path to the same answers asvalidate()across all 3359 suite cases, and still reports zero disagreements.