Skip to content
Permalink
Browse files

Correct name parsing (#69)

  • Loading branch information...
hhrutter committed Mar 13, 2019
1 parent 067897d commit 967c250e0cdf31441df1c79562a00a8df3ab4a52
@@ -17,6 +17,7 @@ limitations under the License.
package pdfcpu

import (
"encoding/hex"
"strconv"
"strings"
"unicode"
@@ -432,6 +433,34 @@ func parseHexLiteral(line *string) (Object, error) {
return HexLiteral(*hexStr), nil
}

func validateNameHexSequence(s string) error {

for i := 0; i < len(s); {
c := s[i]
if c != '#' {
i++
continue
}

// # detected, next 2 chars have to exist.
if len(s) < i+3 {
return errNameObjectCorrupt
}

s1 := s[i+1 : i+3]

// And they have to be hex characters.
_, err := hex.DecodeString(s1)
if err != nil {
return errNameObjectCorrupt
}

i += 3
}

return nil
}

func parseName(line *string) (*Name, error) {

// see 7.3.5
@@ -461,6 +490,12 @@ func parseName(line *string) (*Name, error) {
l = l[:eok]
}

// Validate optional #xx sequences
err := validateNameHexSequence(l)
if err != nil {
return nil, err
}

nameObj := Name(l)
return &nameObj, nil
}
@@ -61,7 +61,10 @@ func TestParseObject(t *testing.T) {
doTestParseObjectOK("<</Key/Value>>", t)
doTestParseObjectOK("<</Key[/Val1/Val2\x0d%gopher\x0atrue]>>", t)
doTestParseObjectOK("[<</k1[/name1]>><</k1[false true null]>>]", t)
doTestParseObjectOK("/Name", t)
doTestParseObjectOK("/Name ", t)
doTestParseObjectFail("/Na#me", t)
doTestParseObjectFail("/Na#2me", t)
doTestParseObjectOK("/Na#20me", t)
doTestParseObjectOK("[null]abc", t)

doTestParseObjectFail("/", t)
@@ -1286,7 +1286,7 @@ func buildFilterPipeline(ctx *Context, filterArray, decodeParmsArr Array, decode
return nil, errors.New("buildFilterPipeline: FilterArray elements corrupt")
}
if decodeParms == nil || decodeParmsArr[i] == nil {
filterPipeline = append(filterPipeline, PDFFilter{Name: filterName.String(), DecodeParms: nil})
filterPipeline = append(filterPipeline, PDFFilter{Name: filterName.Value(), DecodeParms: nil})
continue
}

@@ -71,7 +71,7 @@ func (fo FontObject) Encoding() string {
if found {
switch enc := pdfObject.(type) {
case Name:
encoding = enc.String()
encoding = enc.Value()
default:
encoding = "Custom"
}
@@ -17,6 +17,7 @@ limitations under the License.
package pdfcpu

import (
"bytes"
"encoding/hex"
"fmt"
"io"
@@ -228,7 +229,27 @@ func (nameObject Name) PDFString() string {

// Value returns a string value for this PDF object.
func (nameObject Name) Value() string {
return string(nameObject)

s := string(nameObject)
var b bytes.Buffer

for i := 0; i < len(s); {
c := s[i]
if c != '#' {
b.WriteByte(c)
i++
continue
}

// # detected, next 2 chars have to exist.
// This gets checked during parsing.
s1 := s[i+1 : i+3]
b1, _ := hex.DecodeString(s1)
b.WriteByte(b1[0])
i += 3
}

return b.String()
}

///////////////////////////////////////////////////////////////////////////////////
@@ -571,7 +571,7 @@ func validateColorSpace(xRefTable *pdf.XRefTable, o pdf.Object, excludePatternCS

case pdf.Name:
validateSpecialColorSpaceName := func(s string) bool { return pdf.MemberOf(s, []string{"Pattern"}) }
if ok := validateDeviceColorSpaceName(o.String()) || validateSpecialColorSpaceName(o.String()); !ok {
if ok := validateDeviceColorSpaceName(o.Value()) || validateSpecialColorSpaceName(o.Value()); !ok {
err = errors.Errorf("validateColorSpace: invalid device color space name: %v\n", o)
}

@@ -596,8 +596,8 @@ func validateColorSpaceEntry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName stri
switch o := o.(type) {

case pdf.Name:
if ok := validateDeviceColorSpaceName(o.String()); !ok {
err = errors.Errorf("validateColorSpaceEntry: Name:%s\n", o.String())
if ok := validateDeviceColorSpaceName(o.Value()); !ok {
err = errors.Errorf("validateColorSpaceEntry: Name:%s\n", o.Value())
}

case pdf.Array:
@@ -59,7 +59,7 @@ func validateBG2Entry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName string, ent
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if s != "Default" {
err = errors.New("writeBG2Entry: corrupt name")
}
@@ -88,7 +88,7 @@ func validateUCR2Entry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName string, en
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if s != "Default" {
err = errors.New("writeUCR2Entry: corrupt name")
}
@@ -112,7 +112,7 @@ func validateTransferFunction(xRefTable *pdf.XRefTable, o pdf.Object) (err error
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if s != "Identity" {
return errors.New("validateTransferFunction: corrupt name")
}
@@ -169,7 +169,7 @@ func validateTR2(xRefTable *pdf.XRefTable, o pdf.Object) (err error) {
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if s != "Identity" && s != "Default" {
return errors.Errorf("validateTR2: corrupt name\n")
}
@@ -238,7 +238,7 @@ func validateSpotFunctionEntry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName st
"Double", "InvertedDouble", "Line", "LineX", "LineY", "Round", "Ellipse", "EllipseA",
"InvertedEllipseA", "EllipseB", "EllipseC", "InvertedEllipseC", "Square", "Cross", "Rhomboid"})
}
s := o.String()
s := o.Value()
if !validateSpotFunctionName(s) {
return errors.Errorf("validateSpotFunctionEntry: corrupt name\n")
}
@@ -470,7 +470,7 @@ func validateHalfToneEntry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName string
switch o := o.(type) {

case pdf.Name:
if o.String() != "Default" {
if o.Value() != "Default" {
return errors.Errorf("validateHalfToneEntry: undefined name: %s\n", o)
}

@@ -528,7 +528,7 @@ func validateSoftMaskTransferFunctionEntry(xRefTable *pdf.XRefTable, d pdf.Dict,
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if s != "Identity" {
return errors.New("validateSoftMaskTransferFunctionEntry: corrupt name")
}
@@ -609,7 +609,7 @@ func validateSoftMaskEntry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName string
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if !validateBlendMode(s) {
return errors.Errorf("validateSoftMaskEntry: invalid soft mask: %s\n", s)
}
@@ -342,7 +342,7 @@ func validateFontEncoding(xRefTable *pdf.XRefTable, d pdf.Dict, dictName string,
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
validateFontEncodingName := func(s string) bool {
return pdf.MemberOf(s, []string{"MacRomanEncoding", "MacExpertEncoding", "WinAnsiEncoding"})
}
@@ -436,7 +436,7 @@ func validateCIDToGIDMap(xRefTable *pdf.XRefTable, o pdf.Object) error {
switch o := o.(type) {

case pdf.Name:
s := o.String()
s := o.Value()
if s != "Identity" {
return errors.Errorf("validateCIDToGIDMap: invalid name: %s - must be \"Identity\"\n", s)
}
@@ -660,9 +660,9 @@ func validateType1FontDict(xRefTable *pdf.XRefTable, d pdf.Dict) error {
return err
}

required := xRefTable.Version() >= pdf.V15 || !validateStandardType1Font((*fontName).String())
required := xRefTable.Version() >= pdf.V15 || !validateStandardType1Font((*fontName).Value())
if xRefTable.ValidationMode == pdf.ValidationRelaxed {
required = !validateStandardType1Font((*fontName).String())
required = !validateStandardType1Font((*fontName).Value())
}
// FirstChar, required except for standard 14 fonts. since 1.5 always required, integer
fc, err := validateIntegerEntry(xRefTable, d, dictName, "FirstChar", required, pdf.V10, nil)
@@ -639,7 +639,7 @@ func validateName(xRefTable *pdf.XRefTable, o pdf.Object, validate func(string)
}

// Validation
if validate != nil && !validate(name.String()) {
if validate != nil && !validate(name.Value()) {
return nil, errors.Errorf("validateName: invalid name: %s\n", name)
}

@@ -681,8 +681,8 @@ func validateNameEntry(xRefTable *pdf.XRefTable, d pdf.Dict, dictName, entryName
}

// Validation
if validate != nil && !validate(name.String()) {
return nil, errors.Errorf("validateNameEntry: dict=%s entry=%s invalid dict entry: %s", dictName, entryName, name.String())
if validate != nil && !validate(name.Value()) {
return nil, errors.Errorf("validateNameEntry: dict=%s entry=%s invalid dict entry: %s", dictName, entryName, name.Value())
}

log.Validate.Printf("validateNameEntry end: entry=%s\n", entryName)
@@ -337,15 +337,15 @@ func validateOptionalContentConfigurationDict(xRefTable *pdf.XRefTable, d pdf.Di

if baseState != nil {

if baseState.String() != "ON" {
if baseState.Value() != "ON" {
// ON, optional, content group array
err = validateOptionalContentGroupArray(xRefTable, d, dictName, "ON", sinceVersion)
if err != nil {
return err
}
}

if baseState.String() != "OFF" {
if baseState.Value() != "OFF" {
// OFF, optional, content group array
err = validateOptionalContentGroupArray(xRefTable, d, dictName, "OFF", sinceVersion)
if err != nil {
@@ -220,7 +220,7 @@ func validateOPIDictInks(xRefTable *pdf.XRefTable, o pdf.Object) error {
switch o := o.(type) {

case pdf.Name:
if colorant := o.String(); colorant != "full_color" && colorant != "registration" {
if colorant := o.Value(); colorant != "full_color" && colorant != "registration" {
return errors.New("validateOPIDictInks: corrupt colorant name")
}

0 comments on commit 967c250

Please sign in to comment.
You can’t perform that action at this time.