Let flatecut accept a degenerate Huffman tree
diff --git a/lib/flatecut/flatecut.go b/lib/flatecut/flatecut.go
index 714dcc6..07919bb 100644
--- a/lib/flatecut/flatecut.go
+++ b/lib/flatecut/flatecut.go
@@ -253,7 +253,7 @@
 	for _, x := range lengths {
 		h.counts[x]++
 	}
-	if h.counts[0] == uint32(len(lengths)) {
+	if h.counts[0] >= uint32(len(lengths)) {
 		return 0, 0, errInvalidBadHuffmanTree
 	}
 
@@ -284,7 +284,12 @@
 		}
 	}
 	if remaining != 0 {
-		return 0, 0, errInvalidBadHuffmanTree
+		if ((h.counts[0] + 1) == uint32(len(lengths))) && (h.counts[1] == 1) {
+			// No-op. We allow a degenerate Huffman tree with only one code (of
+			// length 1 bit).
+		} else {
+			return 0, 0, errInvalidBadHuffmanTree
+		}
 	}
 
 	offsets := [maxCodeBits + 1]uint32{}
diff --git a/lib/flatecut/flatecut_test.go b/lib/flatecut/flatecut_test.go
index 95d94e7..5ba070e 100644
--- a/lib/flatecut/flatecut_test.go
+++ b/lib/flatecut/flatecut_test.go
@@ -15,8 +15,10 @@
 package flatecut
 
 import (
+	"bytes"
 	"compress/flate"
 	"io"
+	"io/ioutil"
 	"testing"
 
 	"github.com/google/wuffs/internal/testcut"
@@ -109,3 +111,39 @@
 		t.Fatalf("got %q, want %q", got, want)
 	}
 }
+
+func TestDegenerateHuffmanUnused(t *testing.T) {
+	decode := func(src []byte) string {
+		dst, err := ioutil.ReadAll(
+			flate.NewReader(bytes.NewReader(src)))
+		if err != nil {
+			return err.Error()
+		}
+		return string(dst)
+	}
+
+	full, err := ioutil.ReadFile("../../test/data/artificial/deflate-degenerate-huffman-unused.deflate")
+	if err != nil {
+		t.Fatalf("ReadFile: %v", err)
+	}
+	if len(full) != 15 {
+		t.Fatalf("len(full): got %d, want %d", len(full), 15)
+	}
+
+	if got, want := decode(full), "foo"; got != want {
+		t.Fatalf("before Cut: got %q, want %q", got, want)
+	}
+
+	if encLen, decLen, err := Cut(nil, full, 14); err != nil {
+		t.Fatalf("Cut: %v", err)
+	} else if encLen != 14 {
+		t.Fatalf("encLen: got %d, want %d", encLen, 14)
+	} else if decLen != 2 {
+		t.Fatalf("decLen: got %d, want %d", decLen, 2)
+	}
+
+	if got, want := decode(full[:14]), "fo"; got != want {
+		t.Fatalf("after Cut: got %q, want %q", got, want)
+	}
+
+}
diff --git a/script/make-artificial.go b/script/make-artificial.go
index a8c74c6..4b9c5f6 100644
--- a/script/make-artificial.go
+++ b/script/make-artificial.go
@@ -232,6 +232,7 @@
 func stateDeflate(line string) (stateFunc, error) {
 	g := &deflateGlobals
 	const (
+		cmdB   = "bytes "
 		cmdBNC = "blockNoCompression "
 		cmdBFH = "blockFixedHuffman "
 	)
@@ -240,6 +241,18 @@
 
 	retState := stateFunc(nil)
 	switch {
+	case strings.HasPrefix(line, cmdB):
+		s := line[len(cmdB):]
+		for s != "" {
+			x, ok := uint32(0), false
+			x, s, ok = parseHex(s)
+			if !ok {
+				return nil, fmt.Errorf("bad stateDeflate command: %q", line)
+			}
+			out = append(out, uint8(x))
+		}
+		return stateDeflate, nil
+
 	case strings.HasPrefix(line, cmdBNC):
 		s = line[len(cmdBNC):]
 		retState = stateDeflateNoCompression
diff --git a/test/data/artificial/deflate-degenerate-huffman-unused.deflate b/test/data/artificial/deflate-degenerate-huffman-unused.deflate
new file mode 100644
index 0000000..4751683
--- /dev/null
+++ b/test/data/artificial/deflate-degenerate-huffman-unused.deflate
Binary files differ
diff --git a/test/data/artificial/deflate-degenerate-huffman-unused.deflate.commentary.txt b/test/data/artificial/deflate-degenerate-huffman-unused.deflate.commentary.txt
new file mode 100644
index 0000000..52698b3
--- /dev/null
+++ b/test/data/artificial/deflate-degenerate-huffman-unused.deflate.commentary.txt
@@ -0,0 +1,66 @@
+Running deflate-degenerate-huffman-unused.deflate through script/print-bits.go
+and adding commentary:
+
+    offset  xoffset ASCII   hex     binary
+    000000  0x0000  .       0x05    0b_...._.101  Dynamic Huffman block, final
+    000000  0x0000  .       0x04    0b_0000_0...  NumLCodes: 257
+    000001  0x0001  .       0xC0    0b_...0_0000  NumDCodes: 1
+    000001  0x0001  .       0xC0    0b_110._....  NumCLCodeLengths: 18
+    000002  0x0002  !       0x21    0b_...._...1
+
+Decode the H-CL Huffman table (NumCLCodeLengths = 18). Recall the peculiar
+code_order: 16, 17, 18, 0, 8, ..., 2, 14, 1, 15:
+
+    000002  0x0002  !       0x21    0b_0010_000.  CLCodeLengths: 18 x 3 bits
+    000003  0x0003  .       0x01    0b_0000_0001    CLCLs[ 1] is 2
+    000004  0x0004  .       0x00    0b_0000_0000    CLCLs[ 2] is 2
+    000005  0x0005  .       0x00    0b_0000_0000    CLCLs[17] is 2
+    000006  0x0006  .       0x00    0b_0000_0000    CLCLs[18] is 2
+    000007  0x0007  .       0x80    0b_1000_0000
+    000008  0x0008  .       0xA0    0b_.010_0000
+
+The H-CL Huffman table is:
+"00" -> CodeLength=1
+"01" -> CodeLength=2
+"10" -> CodeLength=17 which means a block of ( 3 + 3_extra_bits) zeroes
+"11" -> CodeLength=18 which means a block of (11 + 7_extra_bits) zeroes
+
+Decode the H-L Huffman table (NumLCodes = 257):
+
+    000008  0x0008  .       0xA0    0b_1..._....  "11" is CL=18: 11+7extra
+    000009  0x0009  .       0xB7    0b_...._...1
+    000009  0x0009  .       0xB7    0b_1011_011.  7extra=91: 102 zeroes
+    000010  0x000A  V       0x56    0b_...._..10  "01" is CL= 2 (102='f')
+    000010  0x000A  V       0x56    0b_...._01..  "10" is CL=17:  3+3extra
+    000010  0x000A  V       0x56    0b_.101_....  3extra=5: 8 zeroes
+    000010  0x000A  V       0x56    0b_0..._....  "00" is CL= 1 (111='o')
+    000011  0x000B  .       0xFE    0b_...._...0
+    000011  0x000B  .       0xFE    0b_...._.11.  "11" is CL=18: 11+7extra
+    000011  0x000B  .       0xFE    0b_1111_1...  7extra=127: 138 zeroes
+    000012  0x000C  7       0x37    0b_...._..11
+    000012  0x000C  7       0x37    0b_...._01..  "10" is CL=17:  3+3extra
+    000012  0x000C  7       0x37    0b_.011_....  3extra=3: 6 zeroes
+    000012  0x000C  7       0x37    0b_0..._....  "01" is CL=2 (256=EOB)
+    000013  0x000D  .       0x89    0b_...._...1
+
+The H-L Huffman table is:
+"0"  -> 'o'
+"10" -> 'f'
+"11" -> EOB
+
+Decode the H-D Huffman table (NumDCodes = 1):
+
+    000013  0x000D  .       0x89    0b_...._.00.  "00" is CL= 1 (DCode 0)
+
+The H-D Huffman table is:
+"0"  -> 0
+This table is incomplete: there is no entry starting with a "1" bit. It is
+therefore degenerate, but not used below.
+
+Apply H-L and H-D.
+
+    000013  0x000D  .       0x89    0b_...0_1...  lcode:  102  literal 'f'
+    000013  0x000D  .       0x89    0b_..0._....  lcode:  111  literal 'o'
+    000013  0x000D  .       0x89    0b_.0.._....  lcode:  111  literal 'o'
+    000013  0x000D  .       0x89    0b_1..._....  lcode:  256  end of block
+    000014  0x000E  .       0x01    0b_...._...1
diff --git a/test/data/artificial/deflate-degenerate-huffman-unused.deflate.make-artificial.txt b/test/data/artificial/deflate-degenerate-huffman-unused.deflate.make-artificial.txt
new file mode 100644
index 0000000..ffd4ded
--- /dev/null
+++ b/test/data/artificial/deflate-degenerate-huffman-unused.deflate.make-artificial.txt
@@ -0,0 +1,7 @@
+# Feed this file to script/make-artificial.go
+
+make deflate
+
+# TODO: blockDynamicHuffman
+# See deflate-degenerate-huffman.deflate.commentary.txt for details.
+bytes 0x05 0xC0 0x21 0x01 0x00 0x00 0x00 0x80 0xA0 0xB7 0x56 0xFE 0x37 0x89 0x01
diff --git a/test/data/artificial/deflate-distance-32768.deflate.commentary.txt b/test/data/artificial/deflate-distance-32768.deflate.commentary.txt
index 84a30b2..fb5d94e 100644
--- a/test/data/artificial/deflate-distance-32768.deflate.commentary.txt
+++ b/test/data/artificial/deflate-distance-32768.deflate.commentary.txt
@@ -18,7 +18,7 @@
     000019  0x0013  .       0xE9    0b_...._...1
     000019  0x0013  .       0xE9    0b_..10_100.  dcode:    5  base:          7
     000019  0x0013  .       0xE9    0b_.1.._....  extra:    1  distance:      8
-	etc
+    etc
     000236  0x00EC  .       0xE9    0b_1..._....  lcode:  284  base:        227
     000237  0x00ED  .       0x91    0b_.001_0001
     000237  0x00ED  .       0x91    0b_1..._....  extra:   17  length:      244