Go: less API stupidity coming from the C++ heritage
This commit is contained in:
parent
9d2412398a
commit
0ea296de67
39
pdf/pdf.go
39
pdf/pdf.go
|
@ -141,21 +141,21 @@ const (
|
||||||
// Lexer is a basic lexical analyser for the Portable Document Format,
|
// Lexer is a basic lexical analyser for the Portable Document Format,
|
||||||
// giving limited error information.
|
// giving limited error information.
|
||||||
type Lexer struct {
|
type Lexer struct {
|
||||||
p []byte // input buffer
|
P []byte // input buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lex *Lexer) read() (byte, bool) {
|
func (lex *Lexer) read() (byte, bool) {
|
||||||
if len(lex.p) > 0 {
|
if len(lex.P) > 0 {
|
||||||
ch := lex.p[0]
|
ch := lex.P[0]
|
||||||
lex.p = lex.p[1:]
|
lex.P = lex.P[1:]
|
||||||
return ch, true
|
return ch, true
|
||||||
}
|
}
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lex *Lexer) peek() (byte, bool) {
|
func (lex *Lexer) peek() (byte, bool) {
|
||||||
if len(lex.p) > 0 {
|
if len(lex.P) > 0 {
|
||||||
return lex.p[0], true
|
return lex.P[0], true
|
||||||
}
|
}
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
@ -671,9 +671,10 @@ func (u *Updater) loadXref(lex *Lexer, loadedEntries map[uint]struct{}) error {
|
||||||
|
|
||||||
var haystackRE = regexp.MustCompile(`(?s:.*)\sstartxref\s+(\d+)\s+%%EOF`)
|
var haystackRE = regexp.MustCompile(`(?s:.*)\sstartxref\s+(\d+)\s+%%EOF`)
|
||||||
|
|
||||||
// Initialize builds the cross-reference table and prepares
|
// NewUpdater initializes an Updater, building the cross-reference table and
|
||||||
// a new trailer dictionary.
|
// preparing a new trailer dictionary.
|
||||||
func (u *Updater) Initialize() error {
|
func NewUpdater(document []byte) (*Updater, error) {
|
||||||
|
u := &Updater{Document: document}
|
||||||
u.updated = make(map[uint]struct{})
|
u.updated = make(map[uint]struct{})
|
||||||
|
|
||||||
// We only need to look for startxref roughly within
|
// We only need to look for startxref roughly within
|
||||||
|
@ -685,7 +686,7 @@ func (u *Updater) Initialize() error {
|
||||||
|
|
||||||
m := haystackRE.FindSubmatch(haystack)
|
m := haystackRE.FindSubmatch(haystack)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return errors.New("cannot find startxref")
|
return nil, errors.New("cannot find startxref")
|
||||||
}
|
}
|
||||||
|
|
||||||
xrefOffset, _ := strconv.ParseInt(string(m[1]), 10, 64)
|
xrefOffset, _ := strconv.ParseInt(string(m[1]), 10, 64)
|
||||||
|
@ -696,20 +697,20 @@ func (u *Updater) Initialize() error {
|
||||||
var throwawayStack []Object
|
var throwawayStack []Object
|
||||||
for {
|
for {
|
||||||
if _, ok := loadedXrefs[xrefOffset]; ok {
|
if _, ok := loadedXrefs[xrefOffset]; ok {
|
||||||
return errors.New("circular xref offsets")
|
return nil, errors.New("circular xref offsets")
|
||||||
}
|
}
|
||||||
if xrefOffset >= int64(len(u.Document)) {
|
if xrefOffset >= int64(len(u.Document)) {
|
||||||
return errors.New("invalid xref offset")
|
return nil, errors.New("invalid xref offset")
|
||||||
}
|
}
|
||||||
|
|
||||||
lex := Lexer{u.Document[xrefOffset:]}
|
lex := Lexer{u.Document[xrefOffset:]}
|
||||||
if err := u.loadXref(&lex, loadedEntries); err != nil {
|
if err := u.loadXref(&lex, loadedEntries); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
trailer, _ := u.parse(&lex, &throwawayStack)
|
trailer, _ := u.parse(&lex, &throwawayStack)
|
||||||
if trailer.Kind != Dict {
|
if trailer.Kind != Dict {
|
||||||
return errors.New("invalid trailer dictionary")
|
return nil, errors.New("invalid trailer dictionary")
|
||||||
}
|
}
|
||||||
if len(loadedXrefs) == 0 {
|
if len(loadedXrefs) == 0 {
|
||||||
u.Trailer = trailer.Dict
|
u.Trailer = trailer.Dict
|
||||||
|
@ -722,7 +723,7 @@ func (u *Updater) Initialize() error {
|
||||||
}
|
}
|
||||||
// FIXME: We don't check for size_t over or underflow.
|
// FIXME: We don't check for size_t over or underflow.
|
||||||
if !prevOffset.IsInteger() {
|
if !prevOffset.IsInteger() {
|
||||||
return errors.New("invalid Prev offset")
|
return nil, errors.New("invalid Prev offset")
|
||||||
}
|
}
|
||||||
xrefOffset = int64(prevOffset.Number)
|
xrefOffset = int64(prevOffset.Number)
|
||||||
}
|
}
|
||||||
|
@ -731,10 +732,10 @@ func (u *Updater) Initialize() error {
|
||||||
|
|
||||||
lastSize, ok := u.Trailer["Size"]
|
lastSize, ok := u.Trailer["Size"]
|
||||||
if !ok || !lastSize.IsInteger() || lastSize.Number <= 0 {
|
if !ok || !lastSize.IsInteger() || lastSize.Number <= 0 {
|
||||||
return errors.New("invalid or missing cross-reference table Size")
|
return nil, errors.New("invalid or missing cross-reference table Size")
|
||||||
}
|
}
|
||||||
u.xrefSize = uint(lastSize.Number)
|
u.xrefSize = uint(lastSize.Number)
|
||||||
return nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get retrieves an object by its number and generation--may return
|
// Get retrieves an object by its number and generation--may return
|
||||||
|
@ -1097,8 +1098,8 @@ func FillInSignature(document []byte, signOff, signLen int,
|
||||||
// PDF 1.6.
|
// PDF 1.6.
|
||||||
func Sign(document []byte,
|
func Sign(document []byte,
|
||||||
key crypto.PrivateKey, certs []*x509.Certificate) ([]byte, error) {
|
key crypto.PrivateKey, certs []*x509.Certificate) ([]byte, error) {
|
||||||
pdf := &Updater{Document: document}
|
pdf, err := NewUpdater(document)
|
||||||
if err := pdf.Initialize(); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue