security(psd): check padding length before scanning it

FilterEffects::parse tested the trailing bytes with
rest.iter().all(|b| b == 0) before checking rest.len() <= 3, so every
loop iteration scanned the whole remaining buffer. A block with many
empty sections produced quadratic CPU work.

Reorder the short-circuiting && so the three-byte length check gates the
zero scan, making each padding check constant work. Behavior is
otherwise identical.

Finding: 4887ae49-cfda-43b0-9296-a1816fc1ddba (CWE-407)
This commit is contained in:
Dylan M. Taylor
2026-10-22 07:11:10 -04:00
parent 58cd22d4ff
commit d0ad7ddb6f
+4 -1
View File
@@ -170,7 +170,10 @@ impl FilterEffects {
let pad = ((4 - len % 4) % 4).min(r.remaining() as u64);
r.skip(pad as usize)?;
let rest = r.peek_rest();
if rest.iter().all(|&b| b == 0) && rest.len() <= 3 {
// Padding is at most three bytes. Check the length before scanning the suffix for
// zeros: otherwise each iteration scans the whole remaining buffer, which is
// quadratic when a block contains many empty sections.
if rest.len() <= 3 && rest.iter().all(|&b| b == 0) {
break;
}
if rest.len() < 8 {