Skip to content

Commit

Permalink
std/png: decode "truncated input" for short chunks
Browse files Browse the repository at this point in the history
Updates #101
  • Loading branch information
nigeltao committed Mar 12, 2023
1 parent ef74175 commit 000b0a3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 47 deletions.
31 changes: 11 additions & 20 deletions release/c/wuffs-unsupported-snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -40795,14 +40795,12 @@ wuffs_png__decoder__do_decode_image_config(
status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
goto ok;
}
label__1__continue:;
while (true) {
while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
if (a_src && a_src->meta.closed) {
status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
goto exit;
}
if (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
status = wuffs_base__make_status(wuffs_base__suspension__short_read);
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
goto label__1__continue;
}
self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
Expand Down Expand Up @@ -43201,13 +43199,10 @@ wuffs_png__decoder__skip_frame(
self->private_impl.f_chunk_type_array[3] = 0;
label__0__continue:;
while (true) {
while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
if (a_src && a_src->meta.closed) {
status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
goto exit;
}
if (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
status = wuffs_base__make_status(wuffs_base__suspension__short_read);
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
goto label__0__continue;
}
self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
Expand Down Expand Up @@ -43446,14 +43441,12 @@ wuffs_png__decoder__do_decode_frame(
goto suspend;
}
}
label__0__continue:;
while (true) {
while (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
if (a_src && a_src->meta.closed) {
status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
goto exit;
}
if (((uint64_t)(io2_a_src - iop_a_src)) < 8) {
status = wuffs_base__make_status(wuffs_base__suspension__short_read);
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
goto label__0__continue;
}
self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32)));
Expand Down Expand Up @@ -43588,14 +43581,12 @@ wuffs_png__decoder__do_decode_frame(
wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi));
}
if (v_status.repr == wuffs_base__suspension__short_read) {
while (true) {
status = wuffs_base__make_status(wuffs_base__suspension__short_read);
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
}
status = wuffs_base__make_status(wuffs_png__error__truncated_input);
goto exit;
}
}
status = v_status;
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
}
label__1__break:;
v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
Expand Down
39 changes: 12 additions & 27 deletions std/png/decode_png.wuffs
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,10 @@ pri func decoder.do_decode_image_config?(dst: nptr base.image_config, src: base.
// IDAT chunk breaks the loop. The only other possible critical chunk is a
// PLTE chunk. We verify PLTE checksums here but ignore other checksums.
while true {
while args.src.length() < 8,
post args.src.length() >= 8,
{
if args.src.is_closed() {
return "#bad chunk"
}
if args.src.length() < 8 {
yield? base."$short read"
} endwhile
continue
}

this.chunk_length = args.src.peek_u32be()
this.chunk_type = (args.src.peek_u64le() >> 32) as base.u32
Expand Down Expand Up @@ -1053,14 +1049,10 @@ pri func decoder.skip_frame?(src: base.io_reader) {
this.chunk_type_array[3] = 0

while true {
while args.src.length() < 8,
post args.src.length() >= 8,
{
if args.src.is_closed() {
return "#bad chunk"
}
if args.src.length() < 8 {
yield? base."$short read"
} endwhile
continue
}

this.chunk_length = args.src.peek_u32be()
this.chunk_type = (args.src.peek_u64le() >> 32) as base.u32
Expand Down Expand Up @@ -1141,14 +1133,10 @@ pri func decoder.do_decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reade
}

while true {
while args.src.length() < 8,
post args.src.length() >= 8,
{
if args.src.is_closed() {
return "#bad chunk"
}
if args.src.length() < 8 {
yield? base."$short read"
} endwhile
continue
}

this.chunk_length = args.src.peek_u32be()
this.chunk_type = (args.src.peek_u64le() >> 32) as base.u32
Expand Down Expand Up @@ -1234,19 +1222,16 @@ pri func decoder.do_decode_frame?(dst: ptr base.pixel_buffer, src: base.io_reade
break
} else if status.is_error() or
((status == base."$short read") and args.src.is_closed()) {
// The input was truncated or invalid. Produce whatever
// pixels we can and then, if truncated, generate "$short
// read" forever.
// The input was invalid or truncated. Produce whatever
// pixels we can.
if this.workbuf_wi <= args.workbuf.length() {
// This might return "#internal error: inconsistent
// workbuf length" because of the ".. this.workbuf_wi".
// We just ignore the error.
this.filter_and_swizzle!(dst: args.dst, workbuf: args.workbuf[.. this.workbuf_wi])
}
if status == base."$short read" {
while true {
yield? base."$short read"
} endwhile
return "#truncated input"
}
}
yield? status
Expand Down

0 comments on commit 000b0a3

Please sign in to comment.