github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/core/fuzz_test.go (about) 1 package core 2 3 import ( 4 "testing" 5 ) 6 7 func init() { 8 // Uncomment when debugging to get trace logging output - to follow flow. 9 // common.SetLogger(common.NewConsoleLogger(common.LogLevelTrace)) 10 } 11 12 // Fuzz tests based on findings with go-fuzz. 13 14 // Test for a crash in 15 // func (this *PdfParser) Trace(obj PdfObject) (PdfObject, error) 16 // when passing a reference to a non-existing object. 17 func TestFuzzParserTrace1(t *testing.T) { 18 parser := PdfParser{} 19 parser.rs, parser.reader, parser.fileSize = makeReaderForText(" /Name") 20 21 ref := &PdfObjectReference{ObjectNumber: -1} 22 obj, err := parser.Trace(ref) 23 24 // Should return non-err, and a nil object. 25 if err != nil { 26 t.Errorf("Fail, err != nil (%v)", err) 27 } 28 29 if _, isNil := obj.(*PdfObjectNull); !isNil { 30 t.Errorf("Fail, obj != PdfObjectNull (%T)", obj) 31 } 32 } 33 34 // Test for an endless loop when stream length referring to itself. 35 /* 36 Found from fuzzing creating an object like: 37 13 0 obj 38 << /Length 13 0 R >> 39 stream 40 xxx 41 endstream 42 43 */ 44 func TestFuzzSelfReference1(t *testing.T) { 45 rawText := `13 0 obj 46 << /Length 13 0 R >> 47 stream 48 xxx 49 endstream 50 ` 51 52 parser := PdfParser{} 53 parser.xrefs = make(XrefTable) 54 parser.objstms = make(ObjectStreams) 55 parser.rs, parser.reader, parser.fileSize = makeReaderForText(rawText) 56 parser.streamLengthReferenceLookupInProgress = map[int64]bool{} 57 58 // Point to the start of the stream (where obj 13 starts). 59 parser.xrefs[13] = XrefObject{ 60 XREF_TABLE_ENTRY, 61 13, 62 0, 63 0, 64 0, 65 0, 66 } 67 68 _, err := parser.ParseIndirectObject() 69 if err == nil { 70 t.Errorf("Should fail with an error") 71 } 72 } 73 74 // Slightly more complex case where the reference number is incorrect, but still points to the same object. 75 func TestFuzzSelfReference2(t *testing.T) { 76 // common.SetLogger(common.NewConsoleLogger(common.LogLevelTrace)) 77 78 rawText := `13 0 obj 79 << /Length 12 0 R >> 80 stream 81 xxx 82 endstream 83 ` 84 85 parser := PdfParser{} 86 parser.xrefs = make(XrefTable) 87 parser.objstms = make(ObjectStreams) 88 parser.rs, parser.reader, parser.fileSize = makeReaderForText(rawText) 89 parser.streamLengthReferenceLookupInProgress = map[int64]bool{} 90 91 // Point to the start of the stream (where obj 13 starts). 92 // NOTE: using incorrect object number here: 93 parser.xrefs[12] = XrefObject{ 94 XREF_TABLE_ENTRY, 95 12, 96 0, 97 0, 98 0, 99 0, 100 } 101 102 _, err := parser.ParseIndirectObject() 103 if err == nil { 104 t.Errorf("Should fail with an error") 105 } 106 } 107 108 // Test for problem where Encrypt pointing a reference to a non-existing object. 109 func TestFuzzIsEncryptedFail1(t *testing.T) { 110 parser := PdfParser{} 111 parser.rs, parser.reader, parser.fileSize = makeReaderForText(" /Name") 112 113 ref := &PdfObjectReference{ObjectNumber: -1} 114 115 parser.trailer = MakeDict() 116 parser.trailer.Set("Encrypt", ref) 117 118 _, err := parser.IsEncrypted() 119 if err == nil { 120 t.Errorf("err == nil: %v. Should fail.", err) 121 return 122 } 123 } 124 125 // Test for trailer Prev entry pointing to an incorrect object type. 126 func TestFuzzInvalidXrefPrev1(t *testing.T) { 127 parser := PdfParser{} 128 parser.rs, parser.reader, parser.fileSize = makeReaderForText(` 129 xref 130 0 1 131 0000000000 65535 f 132 0000000001 00000 n 133 trailer 134 <</Info 1 0 R/Root 2 0 R/Size 17/Prev /Invalid>> 135 startxref 136 0 137 %%EOF 138 `) 139 140 _, err := parser.loadXrefs() 141 if err != nil { 142 t.Errorf("Should not error - just log a debug message regarding an invalid Prev") 143 t.Errorf("Err: %v", err) 144 return 145 } 146 147 }