From 386c92c034d03d3fbfa1c589c8583ec02249ad87 Mon Sep 17 00:00:00 2001 From: Hamza Date: Tue, 20 Oct 2026 17:12:11 +0500 Subject: [PATCH] Render: skipping a number covers the signs reading accepts `read_inner` now reads `-+280` and `++280` as well as `--280`, but `Number::skip` consumed one sign and then required a digit, a dot or a further `-`. So a skip failed where a read succeeded, and `ReaderExt::skip` puts the reader back where it started -- `Object::skip` would leave the number in place rather than step over it. `--280` was already covered, by the `b'-'` arm. One more sign is consumed, and the six sign forms are asserted skippable to the end of the token. Without this the test says `-+280: not skipped`. A third sign is still read and skipped differently (`---280` reads as 0 and skips whole), which was already so before this branch and is left alone. Found in review of #3630. --- vendor/hayro-syntax/src/object/number.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/vendor/hayro-syntax/src/object/number.rs b/vendor/hayro-syntax/src/object/number.rs index 7d3f05b4e..9b89ed709 100644 --- a/vendor/hayro-syntax/src/object/number.rs +++ b/vendor/hayro-syntax/src/object/number.rs @@ -70,6 +70,13 @@ impl Number { impl Skippable for Number { fn skip(r: &mut Reader<'_>, _: bool) -> Option<()> { let has_sign = r.forward_if(|b| b == b'+' || b == b'-').is_some(); + // PdfCraft patch: one more sign, so that skipping a number covers what `read_inner` + // reads. `--280` was already covered by the `b'-'` arm below, but `-+280` and `++280` + // were not, and a skip that fails where a read succeeds puts the reader back where it + // started (#3630 review). + if has_sign { + r.forward_if(|b| b == b'+' || b == b'-'); + } // Some PDFs have weird trailing minuses, so try to accept those as well. match r.peek_byte()? { @@ -368,6 +375,15 @@ mod tests { // The fraction too, and a lone sign is still zero. assert_eq!(Reader::new("--280.5".as_bytes()).read_without_context::().unwrap(), -280.5); assert_eq!(Reader::new("-".as_bytes()).read_without_context::().unwrap(), 0); + + // Skipping covers what reading accepts: a skip that fails where a read succeeds puts the + // reader back where it started, so `Object::skip` would leave the number in place + // (#3630 review). + for src in ["--280", "+-280", "-+280", "++280", "-280", "+280", "--280.5"] { + let mut r = Reader::new(src.as_bytes()); + assert!(r.skip::(false).is_some(), "{src}: not skipped"); + assert!(r.at_end(), "{src}: only part of the number was skipped"); + } } #[test]