Have std/png partially decode invalid images
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 9a3f8c8..5b36a48 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -40549,13 +40549,15 @@
}
if (wuffs_base__status__is_ok(&v_status)) {
goto label__1__break;
- } else if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ } else if (wuffs_base__status__is_error(&v_status) || ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed))) {
if (self->private_impl.f_workbuf_wi <= ((uint64_t)(a_workbuf.len))) {
wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi));
}
- while (true) {
- status = wuffs_base__make_status(wuffs_base__suspension__short_read);
- WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ 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 = v_status;
diff --git a/std/png/decode_png.wuffs b/std/png/decode_png.wuffs
index f66fae2..bdb98d8 100644
--- a/std/png/decode_png.wuffs
+++ b/std/png/decode_png.wuffs
@@ -1199,18 +1199,22 @@
status =? this.decode_pass?(src: args.src, workbuf: args.workbuf)
if status.is_ok() {
break
- } else if (status == base."$short read") and args.src.is_closed() {
- // The input was truncated. Produce whatever pixels we can
- // and then generate "$short read" forever.
+ } 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.
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])
}
- while true {
- yield? base."$short read"
- } endwhile
+ if status == base."$short read" {
+ while true {
+ yield? base."$short read"
+ } endwhile
+ }
}
yield? status
} endwhile