From 1cf24c2c9836d8988f4ccf9591638fdc75827931 Mon Sep 17 00:00:00 2001 From: mpl Date: Fri, 18 May 2018 03:34:33 +0200 Subject: [PATCH] tiff: ignore all trailing NULLs in case of misleading Count 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 https://github.com/perkeep/perkeep/issues/1127 This change therefore makes sure to remove all trailing NULLs from the data, in the case of DTAscii at least. --- tiff/tag.go | 11 +++++++++-- tiff/tiff_test.go | 18 ++++++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/tiff/tag.go b/tiff/tag.go index 95d4b28..b9ce791 100644 --- a/tiff/tag.go +++ b/tiff/tag.go @@ -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 diff --git a/tiff/tiff_test.go b/tiff/tiff_test.go index 5db348d..6f588d5 100644 --- a/tiff/tiff_test.go +++ b/tiff/tiff_test.go @@ -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", ""}, @@ -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) + } } }