Skip to content

basenc: preserve decoded prefixes on invalid input - #15485

Open
limadog9 wants to merge 1 commit into
uutils:mainfrom
limadog9:fix/basenc-partial-output-6008
Open

limadog9 wants to merge 1 commit into
uutils:mainfrom
limadog9:fix/basenc-partial-output-6008

Conversation

@limadog9

Copy link
Copy Markdown
Contributor

Invalid or incomplete input discarded decoded data from the current batch. Preserve complete output before reporting the error across the shared decoders, keep valid input batched, and handle unpadded base64url tails. Add regressions for all standard encodings, batch boundaries, and read failures.

Validation: 84 base32/base64/basenc integration tests and 3 unit tests pass; eight GNU differential cases pass.

Closes #6008

@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/basenc/basenc. tests/basenc/basenc is passing on 'main'. Maybe you have to rebase?

@limadog9
limadog9 force-pushed the fix/basenc-partial-output-6008 branch from 7168c18 to 3f383ad Compare October 18, 2026 19:55
@sylvestre

Copy link
Copy Markdown
Contributor

@limadog9 please fix the regressions when they happen :)

@sylvestre

Copy link
Copy Markdown
Contributor

The GNU bot shows tests/basenc/base64 and tests/basenc/basenc failing now that the seds are gone.

Comment thread src/uu/base32/src/base_common.rs Outdated
break;
}
}
if all_valid {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this now accepts padding in the middle (YQ==YQ==), is it intended? please split it out with a test if so

Comment thread src/uu/base32/src/base_common.rs Outdated
use std::io::{self, BufReader, Cursor, Read};

#[test]
fn buffered_decode_keeps_prefix_on_error() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicates the z85 integration test, do we need it?

Comment thread src/uucore/src/lib/features/encoding.rs Outdated
true
}

fn validate_decode_buffer(&self, input: &[u8]) -> UResult<()> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this depends on the read buffer size, the exact GNU quirk discussed in #6008
#6008 (comment)
do we really want to replicate it?

Comment thread src/uucore/src/lib/features/encoding.rs Outdated
fn validate_decode_buffer(&self, input: &[u8]) -> UResult<()> {
// Unlike ordinary garbage, the standard base64 symbols are rejected
// before base64url starts decoding the buffer.
if self.encoding == data_encoding::BASE64URL

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

three self.encoding == BASE64URL checks in a generic wrapper, could it be a dedicated type or flag instead?

Comment thread src/uucore/src/lib/features/encoding.rs Outdated
}
}

fn pad_remainder(&self, remainder: &[u8]) -> Option<PadResult> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unpadded base64url tail is unrelated to the issue, please split into another pr

Comment thread util/build-gnu.sh
sed -i "s/\(baddecode.*OUT=>\"\).*\"/\1\"/g" tests/basenc/base64.pl
sed -i "s/\(\(b2[ml]_[69]\|z85_8\|z85_35\).*OUT=>\)[^}]*\(.*\)/\1\"\"\3/g" tests/basenc/basenc.pl

# add "error: " to the expected error message

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing these seds makes tests/basenc/base64 and tests/basenc/basenc fail now, please check which cases still differ
i do prefer our behavior here

@limadog9
limadog9 force-pushed the fix/basenc-partial-output-6008 branch from 3f383ad to 5f4c5e3 Compare October 18, 2026 22:50
@codspeed

codspeed Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 3%

⚠️ 121 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

ℹ️ 1 benchmark has no flame graph

The flamegraph could not be generated because too much time was spent in runtime internals, making the visualization not useful for performance analysis.

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 400 untouched benchmarks
⏩ 70 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ ⚠️ Simulation du_all_wide_tree[(5000, 500)] 33.8 ms 34.8 ms -3%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing limadog9:fix/basenc-partial-output-6008 (93eff75) with main (d2d9694)

Open in CodSpeed

Footnotes

  1. 70 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@limadog9

Copy link
Copy Markdown
Contributor Author

Updated

Preserve decoded bytes before invalid input, padding, trailing bits and
read failures without changing the codec padding rules. Keep valid input
batched.

Adjust the GNU base64url expectation to retain the valid prefix before
an invalid alphabet character. Both GNU basenc and base64 suites pass,
along with 85 native decoder integration tests.

Closes uutils#6008.
@limadog9
limadog9 force-pushed the fix/basenc-partial-output-6008 branch from 5f4c5e3 to 93eff75 Compare October 19, 2026 10:27

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

basenc: emit partial output on invalid input

2 participants