github.com/signintech/pdft@v0.5.0/pdf_obj_data.go (about) 1 package pdft 2 3 import ( 4 "bytes" 5 "crypto/rc4" 6 "errors" 7 8 gopdf "github.com/signintech/pdft/minigopdf" 9 ) 10 11 // PDFObjData byte of obj 12 type PDFObjData struct { 13 objID int 14 data []byte 15 } 16 17 func (p *PDFObjData) parse(raw *[]byte, stratoffset int) error { 18 19 tmp := (*raw)[stratoffset:] 20 endObjIndex := regexpEndObj.FindAllIndex(tmp, 1) 21 if len(endObjIndex) <= 0 { 22 return errors.New("bad endobj") 23 } 24 endObjOffsetBefore := endObjIndex[0][0] + stratoffset 25 26 tmp = (*raw)[stratoffset:endObjOffsetBefore] 27 startObjIndex := regexpStartObj.FindAllIndex(tmp, 1) 28 if len(startObjIndex) <= 0 { 29 return errors.New("bad start obj") 30 } 31 32 startObjOffsetAfter := startObjIndex[0][1] 33 startObjOffset := startObjIndex[0][0] 34 startObjLine := tmp[startObjOffset:startObjOffsetAfter] 35 data := tmp[startObjOffsetAfter:] 36 objID, err := objIDFromStartObjLine(string(startObjLine)) 37 if err != nil { 38 return err 39 } 40 41 p.objID = objID 42 p.data = data 43 44 return nil 45 } 46 47 // ReadProperties read all obj Properties 48 func (p *PDFObjData) readProperties() (*PDFObjPropertiesData, error) { 49 var props PDFObjPropertiesData 50 err := readProperties(&p.data, &props) 51 if err != nil { 52 return nil, err 53 } 54 return &props, nil 55 } 56 57 func (p *PDFObjData) setProperties(props *PDFObjPropertiesData) { 58 var data bytes.Buffer 59 data.WriteString("<<\n") 60 for _, prop := range *props { 61 data.WriteString("/" + prop.key + " " + prop.rawVal) 62 } 63 data.WriteString(">>\n") 64 p.data = data.Bytes() 65 } 66 67 func (p *PDFObjData) encrypt(protection *gopdf.PDFProtection) error { 68 69 stream := []byte("stream") 70 endstream := []byte("endstream") 71 start := bytes.Index(p.data, stream) 72 if start != -1 { 73 end := bytes.LastIndex(p.data, endstream) 74 75 var head, body bytes.Buffer 76 head.Write(p.data[0:start]) 77 body.Write(p.data[start+len(stream) : end]) 78 tmp := bytes.Trim(body.Bytes(), "\r\n") 79 tmp = bytes.Trim(tmp, "\n") 80 bodyRc4, err := rc4Cip(protection.Objectkey(p.objID), tmp) 81 if err != nil { 82 return err 83 } 84 85 var data bytes.Buffer 86 data.Write(head.Bytes()) 87 data.Write(stream) 88 data.WriteString("\n") 89 data.Write(bodyRc4) 90 data.WriteString("\n") 91 data.Write(endstream) 92 p.data = data.Bytes() 93 } 94 return nil 95 } 96 97 func rc4Cip(key []byte, src []byte) ([]byte, error) { 98 cip, err := rc4.NewCipher(key) 99 if err != nil { 100 return nil, err 101 } 102 dest := make([]byte, len(src)) 103 cip.XORKeyStream(dest, src) 104 return dest, nil 105 }