Let gif "ignore too much" quirk skip lzw errors

The modified test/data/*/*.gif files differ by only one byte:
 00000000  47 49 46 38 39 61 02 00  02 00 81 00 00 00 00 ff  |GIF89a..........|
 00000010  11 00 ff 22 00 ff 33 00  ff 2c 00 00 00 00 02 00  |..."..3..,......|
-00000020  02 00 00 02 02 84 f1 00  3b                       |........;|
+00000020  02 00 00 02 02 84 5d 00  3b                       |......].;|

The etc-good-lzw.gif bits have changed, even though the
etc-good-lzw.etc.txt file only had comments added, due to a Go standard
library change: "compress/lzw: output a Clear code first, per GIF spec"
https://github.com/golang/go/commit/9c1dbdf60edbffeff10f58af21fa055eb0fdd29f

Updates PR #57
Updates https://crbug.com/1270631
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index ff21071..a8aeb09 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -31152,6 +31152,30 @@
           goto label__outer__continue;
         } else if (v_lzw_status.repr == wuffs_base__suspension__short_write) {
           goto label__inner__continue;
+        } else if (self->private_impl.f_quirks[3] && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) && (self->private_impl.f_interlace == 0)) {
+          if (v_need_block_size || (v_block_size > 0)) {
+            self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
+            WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+            if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+              self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+              iop_a_src = io2_a_src;
+              status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+              goto suspend;
+            }
+            iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
+            if (a_src) {
+              a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+            }
+            WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+            status = wuffs_gif__decoder__skip_blocks(self, a_src);
+            if (a_src) {
+              iop_a_src = a_src->data.ptr + a_src->meta.ri;
+            }
+            if (status.repr) {
+              goto suspend;
+            }
+          }
+          goto label__outer__break;
         }
         status = v_lzw_status;
         if (wuffs_base__status__is_error(&status)) {
diff --git a/std/gif/decode_gif.wuffs b/std/gif/decode_gif.wuffs
index b5de857..f2a3309 100644
--- a/std/gif/decode_gif.wuffs
+++ b/std/gif/decode_gif.wuffs
@@ -954,6 +954,17 @@
 				continue.outer
 			} else if lzw_status == base."$short write" {
 				continue.inner
+			} else if this.quirks[QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA - QUIRKS_BASE] and
+				(this.dst_y >= this.frame_rect_y1) and (this.interlace == 0) {
+				// It's invalid LZW-compressed data, but we still have a full
+				// frame and have opted in to QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA,
+				// so treat it like the lzw_status.is_ok() case, other than not
+				// clearing this.previous_lzw_decode_ended_abruptly.
+				if need_block_size or (block_size > 0) {
+					args.src.skip_u32?(n: block_size as base.u32)
+					this.skip_blocks?(src: args.src)
+				}
+				break.outer
 			}
 			return lzw_status
 		} endwhile.inner
diff --git a/test/c/std/gif.c b/test/c/std/gif.c
index ddbdc83..b620bc8 100644
--- a/test/c/std/gif.c
+++ b/test/c/std/gif.c
@@ -1598,11 +1598,20 @@
   wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
       .data = g_src_slice_u8,
   });
+
+  src.meta = wuffs_base__empty_io_buffer_meta();
+  CHECK_STRING(read_file(
+      &src, "test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif"));
+  CHECK_STRING(do_test_wuffs_gif_decode_expecting(
+      src, 0, wuffs_lzw__error__bad_code, false));
+
+  src.meta = wuffs_base__empty_io_buffer_meta();
   CHECK_STRING(read_file(
       &src, "test/data/artificial-gif/pixel-data-too-much-good-lzw.gif"));
+  CHECK_STRING(do_test_wuffs_gif_decode_expecting(
+      src, 0, wuffs_base__error__too_much_data, false));
 
-  return do_test_wuffs_gif_decode_expecting(
-      src, 0, wuffs_base__error__too_much_data, false);
+  return NULL;
 }
 
 const char*  //
@@ -1611,11 +1620,20 @@
   wuffs_base__io_buffer src = ((wuffs_base__io_buffer){
       .data = g_src_slice_u8,
   });
+
+  src.meta = wuffs_base__empty_io_buffer_meta();
+  CHECK_STRING(read_file(
+      &src, "test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif"));
+  CHECK_STRING(do_test_wuffs_gif_decode_expecting(
+      src, WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA, NULL, false));
+
+  src.meta = wuffs_base__empty_io_buffer_meta();
   CHECK_STRING(read_file(
       &src, "test/data/artificial-gif/pixel-data-too-much-good-lzw.gif"));
+  CHECK_STRING(do_test_wuffs_gif_decode_expecting(
+      src, WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA, NULL, false));
 
-  return do_test_wuffs_gif_decode_expecting(
-      src, WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA, NULL, false);
+  return NULL;
 }
 
 const char*  //
diff --git a/test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif b/test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif
new file mode 100644
index 0000000..d53dfba
--- /dev/null
+++ b/test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif
Binary files differ
diff --git a/test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif.make-artificial.txt b/test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif.make-artificial.txt
new file mode 100644
index 0000000..9ba0a36
--- /dev/null
+++ b/test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif.make-artificial.txt
@@ -0,0 +1,37 @@
+# Feed this file to script/make-artificial.go
+
+make gif
+
+header
+
+image {
+	imageWidthHeight 2 2
+	palette {
+		0x00 0x00 0xFF
+		0x11 0x00 0xFF
+		0x22 0x00 0xFF
+		0x33 0x00 0xFF
+	}
+}
+
+frame {
+	frameLeftTopWidthHeight 0 0 2 2
+}
+
+# The frame area is 4 pixels and we supply 4 but then an invalid LZW code.
+# Compare with pixel-data-too-much-good-lzw.gif.make-artificial.txt
+#
+# The disassembly (see also std/lzw/README.md) is:
+#
+# 0x02                              LZW literal width.
+# 0x02                              GIF block length.
+# 0x84 0xF1 = 0b1111_0001_1000_0100 (little endian).
+#             0b...._...._...._.100 3-bit Clear code.
+#             0b...._...._..00_0... 3-bit Literal 0x00.
+#             0b...._...1_10.._.... 3-bit Copy code (2 bytes).
+#             0b...._000._...._.... 3-bit Literal 0x00.
+#             0b1111_...._...._.... 4-bit Invalid code.
+# 0x00                              GIF block terminator.
+bytes 0x02 0x02 0x84 0xF1 0x00
+
+trailer
diff --git a/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif b/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif
index 573ec88..91ba6a3 100644
--- a/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif
+++ b/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif
Binary files differ
diff --git a/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif.make-artificial.txt b/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif.make-artificial.txt
index 5f02c1b..166c8cf 100644
--- a/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif.make-artificial.txt
+++ b/test/data/artificial-gif/pixel-data-too-much-good-lzw.gif.make-artificial.txt
@@ -17,7 +17,21 @@
 frame {
 	frameLeftTopWidthHeight 0 0 2 2
 }
-# The frame is 4 pixels, but we supply 5.
+
+# The frame area is 4 pixels but we supply 5 (that's still valid LZW data).
+# Compare with pixel-data-too-much-bad-lzw.gif.make-artificial.txt
+#
+# The equivalent bytes' disassembly (see also std/lzw/README.md) is:
+#
+# 0x02                              LZW literal width.
+# 0x02                              GIF block length.
+# 0x84 0x5D = 0b0101_1101_1000_0100 (little endian).
+#             0b...._...._...._.100 3-bit Clear code.
+#             0b...._...._..00_0... 3-bit Literal 0x00.
+#             0b...._...1_10.._.... 3-bit Copy code (2 bytes).
+#             0b...._110._...._.... 3-bit Copy code (2 bytes).
+#             0b0101_...._...._.... 4-bit End code.
+# 0x00                              GIF block terminator.
 lzw 2 0x00 0x00 0x00 0x00 0x00
 
 trailer
diff --git a/test/nia-checksums-of-data.txt b/test/nia-checksums-of-data.txt
index 5c65b37..b3f390e 100644
--- a/test/nia-checksums-of-data.txt
+++ b/test/nia-checksums-of-data.txt
@@ -16,6 +16,7 @@
 76c44866 test/data/artificial-gif/no-frames.gif
 6ec818c3 test/data/artificial-gif/pixel-data-none.gif
 5e57adb2 test/data/artificial-gif/pixel-data-not-enough.gif
+3e29f88a test/data/artificial-gif/pixel-data-too-much-bad-lzw.gif
 3e29f88a test/data/artificial-gif/pixel-data-too-much-good-lzw.gif
 f50d1d50 test/data/artificial-gif/small-frame-interlaced.gif
 beaec397 test/data/artificial-gif/transparent-index.gif