Skip to content

Commit

Permalink
Fix #755
Browse files Browse the repository at this point in the history
  • Loading branch information
hhrutter committed Dec 13, 2023
1 parent e3358c4 commit e33b502
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 29 deletions.
2 changes: 1 addition & 1 deletion pkg/pdfcpu/crypto.go
Expand Up @@ -1087,7 +1087,7 @@ func decryptBytes(b []byte, objNr, genNr int, encKey []byte, needAES bool, r int
// decryptString decrypts s using RC4 or AES.
func decryptString(s string, objNr, genNr int, key []byte, needAES bool, r int) ([]byte, error) {

bb, err := types.Unescape(s, true)
bb, err := types.Unescape(s)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pdfcpu/model/dereference.go
Expand Up @@ -377,7 +377,7 @@ func (xRefTable *XRefTable) DereferenceStringEntryBytes(d types.Dict, key string

switch o := o.(type) {
case types.StringLiteral:
bb, err := types.Unescape(o.Value(), false)
bb, err := types.Unescape(o.Value())
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pdfcpu/model/xreftable.go
Expand Up @@ -1563,7 +1563,7 @@ func (xRefTable *XRefTable) IDFirstElement() (id []byte, err error) {
return nil, errors.New("pdfcpu: ID must contain hex literals or string literals")
}

bb, err := types.Unescape(sl.Value(), false)
bb, err := types.Unescape(sl.Value())
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pdfcpu/types/dict.go
Expand Up @@ -561,7 +561,7 @@ func (d Dict) StringEntryBytes(key string) ([]byte, error) {

s := d.StringLiteralEntry(key)
if s != nil {
bb, err := Unescape(s.Value(), false)
bb, err := Unescape(s.Value())
if err != nil {
return nil, err
}
Expand Down
37 changes: 20 additions & 17 deletions pkg/pdfcpu/types/string.go
Expand Up @@ -107,10 +107,7 @@ func regularChar(c byte, esc bool) bool {
}

// Unescape resolves all escape sequences of s.
func Unescape(s string, enc bool) ([]byte, error) {

// TODO remove "enc" parameter.

func Unescape(s string) ([]byte, error) {
var esc bool
var longEol bool
var octalCode string
Expand All @@ -129,6 +126,21 @@ func Unescape(s string, enc bool) ([]byte, error) {
}
}

if len(octalCode) > 0 {
if strings.ContainsRune("01234567", rune(c)) {
octalCode = octalCode + string(c)
if len(octalCode) == 3 {
b.WriteByte(ByteForOctalString(octalCode))
octalCode = ""
esc = false
}
continue
}
b.WriteByte(ByteForOctalString(octalCode))
octalCode = ""
esc = false
}

if regularChar(c, esc) {
b.WriteByte(c)
continue
Expand All @@ -149,19 +161,6 @@ func Unescape(s string, enc bool) ([]byte, error) {

// escaped = true && any other than \

if len(octalCode) > 0 {
if !strings.ContainsRune("01234567", rune(c)) {
return nil, errors.Errorf("Unescape: illegal octal sequence detected %X", octalCode)
}
octalCode = octalCode + string(c)
if len(octalCode) == 3 {
b.WriteByte(ByteForOctalString(octalCode))
octalCode = ""
esc = false
}
continue
}

// Ignore \eol line breaks.
if c == 0x0A {
esc = false
Expand Down Expand Up @@ -189,6 +188,10 @@ func Unescape(s string, enc bool) ([]byte, error) {
esc = false
}

if len(octalCode) > 0 {
b.WriteByte(ByteForOctalString(octalCode))
}

return b.Bytes(), nil
}

Expand Down
60 changes: 54 additions & 6 deletions pkg/pdfcpu/types/string_test.go
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package types

import (
"bytes"
"testing"
)

Expand Down Expand Up @@ -52,9 +53,56 @@ func TestByteForOctalString(t *testing.T) {
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
actual := ByteForOctalString(test.input)
if actual != test.expected {
t.Errorf("got %x; want %x", test.expected, actual)
got := ByteForOctalString(test.input)
if got != test.expected {
t.Errorf("got %x; want %x", got, test.expected)
}
})
}
}

func TestUnescapeStringWithOctal(t *testing.T) {
tests := []struct {
input string
expected []byte
}{
{
"\\5",
[]byte{0x05},
},
{
"\\5a",
[]byte{0x05, 'a'},
},
{
"\\5\\5",
[]byte{0x05, 0x05},
},
{
"\\53",
[]byte{'+'},
},
{
"\\53a",
[]byte{'+', 'a'},
},
{
"\\053",
[]byte{'+'},
},
{
"\\0053",
[]byte{0x05, '3'},
},
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
got, err := Unescape(test.input)
if err != nil {
t.Fail()
}
if !bytes.Equal(got, test.expected) {
t.Errorf("got %x; want %x", got, test.expected)
}
})
}
Expand Down Expand Up @@ -116,12 +164,12 @@ func TestDecodeName(t *testing.T) {
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
actual, err := DecodeName(test.input)
got, err := DecodeName(test.input)
if err != nil {
t.Fail()
}
if actual != test.expected {
t.Errorf("got %x; want %x", test.expected, actual)
if got != test.expected {
t.Errorf("got %x; want %x", got, test.expected)
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pdfcpu/types/utf16.go
Expand Up @@ -127,7 +127,7 @@ func EscapeUTF16String(s string) (*string, error) {

// StringLiteralToString returns the best possible string rep for a string literal.
func StringLiteralToString(sl StringLiteral) (string, error) {
bb, err := Unescape(sl.Value(), false)
bb, err := Unescape(sl.Value())
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/pdfcpu/writeImage.go
Expand Up @@ -127,7 +127,7 @@ func colorLookupTable(xRefTable *model.XRefTable, o types.Object) ([]byte, error
switch o := o.(type) {

case types.StringLiteral:
return types.Unescape(o.Value(), false)
return types.Unescape(o.Value())

case types.HexLiteral:
return o.Bytes()
Expand Down

0 comments on commit e33b502

Please sign in to comment.