Skip to content

Commit

Permalink
tiff: ignore all trailing NULLs in case of misleading Count
Browse files Browse the repository at this point in the history
As it can apparently happen with some camera software
(https://user-images.githubusercontent.com/2621/39392188-71a66fc4-4a66-11e8-9e3b-694163efa643.jpg),
sometimes a tag bytes will not only have a bunch of trailing NULLs, but
the Count for the data in that tag will be wrongly set too. i.e. instead
of being set to the actual number of relevant bytes to read, it will
be set to the full number of bytes, trailing zeroes included.

As a consequence, the Tag.strVal returned would include these trailing
NULLs too, which would lead to bugs such as
perkeep/perkeep#1127

This change therefore makes sure to remove all trailing NULLs from the
data, in the case of DTAscii at least.
  • Loading branch information
mpl committed May 18, 2018
1 parent fb35d3c commit 1cf24c2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
11 changes: 9 additions & 2 deletions tiff/tag.go
Expand Up @@ -179,8 +179,15 @@ func (t *Tag) convertVals() error {

switch t.Type {
case DTAscii:
if len(t.Val) > 0 {
t.strVal = string(t.Val[:len(t.Val)-1]) // ignore the last byte (NULL).
if len(t.Val) <= 0 {
break
}
nullPos := bytes.IndexByte(t.Val, 0)
if nullPos == -1 {
t.strVal = string(t.Val)
} else {
// ignore all trailing NULL bytes, in case of a broken t.Count
t.strVal = string(t.Val[:nullPos])
}
case DTByte:
var v uint8
Expand Down
18 changes: 16 additions & 2 deletions tiff/tiff_test.go
Expand Up @@ -49,6 +49,13 @@ var set1 = []tagTest{
input{"0100", "0200", "06000000", "12000000", "111213141516"},
output{0x0001, DataType(0x0002), 0x0006, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}},
},
// broken Count, because it includes all trailing NULL bytes, as is the case in
// https://user-images.githubusercontent.com/2621/39392188-71a66fc4-4a66-11e8-9e3b-694163efa643.jpg
tagTest{
input{"0001", "0002", "00000009", "00000012", "111213141516000000"},
input{"0100", "0200", "09000000", "12000000", "111213141516000000"},
output{0x0001, DataType(0x0002), 0x0009, []byte{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}},
},
//////////// int (1-byte) type ////////////////
tagTest{
input{"0001", "0001", "00000001", "11000000", ""},
Expand Down Expand Up @@ -161,8 +168,15 @@ func testSingle(t *testing.T, order binary.ByteOrder, in input, out output, i in
if tg.Count != out.count {
t.Errorf("(%v) tag %v component count decode: expected %v, got %v", order, i, out.count, tg.Count)
}
if !bytes.Equal(tg.Val, out.val) {
t.Errorf("(%v) tag %v value decode: expected %v, got %v", order, i, out.val, tg.Val)
if tg.Type == DTAscii && in.val != "" {
strOut := string(out.val)
if tg.strVal != strOut {
t.Errorf("(%v) tag %v string value decode: expected %q, got %q", order, i, strOut, tg.strVal)
}
} else {
if !bytes.Equal(tg.Val, out.val) {
t.Errorf("(%v) tag %v value decode: expected %q, got %q", order, i, out.val, tg.Val)
}
}
}

Expand Down

0 comments on commit 1cf24c2

Please sign in to comment.