From f5777ce744906ce5ace92ed3798105c9e69f1030 Mon Sep 17 00:00:00 2001 From: Michael Macias Date: Tue, 24 Sep 2024 10:21:30 -0500 Subject: [PATCH] vcf/io/writer/record/samples/sample/value/integer: Validate value --- noodles-vcf/CHANGELOG.md | 2 +- .../record/samples/sample/value/integer.rs | 24 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/noodles-vcf/CHANGELOG.md b/noodles-vcf/CHANGELOG.md index 29ac20713..2dd2fa63d 100644 --- a/noodles-vcf/CHANGELOG.md +++ b/noodles-vcf/CHANGELOG.md @@ -4,7 +4,7 @@ ### Changed - * vcf/io/writer/record/info/field/value/integer: Validate value. + * vcf/io/writer/record: Validate integer value. Integer values must now be > -2^31 + 7. See _The Variant Call Format Specification: VCFv4.5 and BCFv2.2_ (2024-06-28) § 1.3 "Data types". diff --git a/noodles-vcf/src/io/writer/record/samples/sample/value/integer.rs b/noodles-vcf/src/io/writer/record/samples/sample/value/integer.rs index 9b4f428d3..77e4b1e1b 100644 --- a/noodles-vcf/src/io/writer/record/samples/sample/value/integer.rs +++ b/noodles-vcf/src/io/writer/record/samples/sample/value/integer.rs @@ -4,7 +4,21 @@ pub(super) fn write_integer(writer: &mut W, n: i32) -> io::Result<()> where W: Write, { - write!(writer, "{n}") + if is_valid(n) { + write!(writer, "{n}") + } else { + Err(io::Error::new( + io::ErrorKind::InvalidInput, + "invalid integer", + )) + } +} + +// § 1.3 "Data types" (2024-06-28): "For the Integer type, the values from -2^31 to -2^31 + 7 +// cannot be stored in the binary version and therefore are disallowed in both VCF and BCF..." +fn is_valid(n: i32) -> bool { + const MIN: i32 = i32::MIN + 7; + n > MIN } #[cfg(test)] @@ -22,10 +36,16 @@ mod tests { let mut buf = Vec::new(); - t(&mut buf, i32::MIN, b"-2147483648")?; + t(&mut buf, i32::MIN + 8, b"-2147483640")?; t(&mut buf, 0, b"0")?; t(&mut buf, i32::MAX, b"2147483647")?; + buf.clear(); + assert!(matches!( + write_integer(&mut buf, i32::MIN), + Err(e) if e.kind() == io::ErrorKind::InvalidInput + )); + Ok(()) } }