Skip to content

Commit

Permalink
Make parsing of types and GPS tags more robust
Browse files Browse the repository at this point in the history
Don't assume that we cannot encounter type IDs other than the specification
says. It does happen. Also, don't assume that the string values for
GPSProcessingMethod and GPSAreaInformation will always be correctly formatted
strings.
  • Loading branch information
mattiasw committed Oct 20, 2014
1 parent 80a2fa8 commit 84ddc9f
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 49 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "exifreader",
"version": "1.1.0",
"version": "1.1.1",
"homepage": "https://github.com/mattiasw/ExifReader",
"authors": [
"Mattias Wallander <mattias@wallander.eu>"
Expand Down
2 changes: 1 addition & 1 deletion component.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "exifreader",
"repo": "mattiasw/ExifReader",
"description": "Client-side Exif parser",
"version": "1.1.0",
"version": "1.1.1",
"keywords": ["exif", "image", "jpg", "jpeg", "meta"],
"dependencies": {},
"license": "GNU LGPL",
Expand Down
77 changes: 45 additions & 32 deletions js/ExifReader.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 27 additions & 2 deletions spec/ExifReader.spec.coffee
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
###
# ExifReader 1.1.0
# ExifReader 1.1.1
# http://github.com/mattiasw/exifreader
# Copyright (C) 2011 Mattias Wallander <mattias@wallander.eu>
# Copyright (C) 2011-2014 Mattias Wallander <mattias@wallander.eu>
# Licensed under the GNU Lesser General Public License version 3 or later
# See license text at http://www.gnu.org/licenses/lgpl.txt
###
Expand Down Expand Up @@ -230,6 +230,11 @@ describe 'ExifReader', ->
@exif._dataView = getDataView '\x47\x11\x00\x02\x00\x00\x00\x06\x00\x00\x00\x0c\x41\x42\x43\x44\x45\x00'
expect(@exif._readTag('0th', 0).description).toEqual 'ABCDE'

it 'should be able to handle tag with faulty type', ->
@exif._tagNames['0th'][0x4711] = 'MyFaultyTypeTag'
@exif._dataView = getDataView '\x47\x11\x00\x08\x00\x00\x00\x00'
expect(@exif._readTag('0th', 0)).toBeUndefined()

it 'should return undefined value for undefined tag names', ->
exif = @exif
expect(exif.getTagValue('MyUndefinedTagName')).toBeUndefined()
Expand Down Expand Up @@ -317,6 +322,14 @@ describe 'ExifReader', ->
@exif._dataView = getDataView '\x92\x86\x00\x07\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00'
expect(@exif._readTag('exif', 0).description).toEqual '[Undefined encoding]'

it 'should report correct name for FNumber', ->
@exif._dataView = getDataView '\x82\x9d\x00\x05\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x01\x02\x00\x00\x03\x04'
expect(@exif._readTag('exif', 0).name).toEqual 'FNumber'

it 'should report correct description for FNumber', ->
@exif._dataView = getDataView '\x82\x9d\x00\x05\x00\x00\x00\x01\x00\x00\x00\x0c\x00\x00\x01\x02\x00\x00\x03\x04'
expect(@exif._readTag('exif', 0).description).toEqual 0x102 / 0x304

it 'should report correct description for ExposureProgram', ->
@exif._dataView = getDataView '\x88\x22\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00'
expect(@exif._readTag('exif', 0).description).toEqual 'Undefined'
Expand Down Expand Up @@ -583,6 +596,10 @@ describe 'ExifReader', ->
@exif._dataView = getDataView '\x00\x00\x00\x01\x00\x00\x00\x04\x02\x02\x00\x00'
expect(@exif._readTag('gps', 0).description).toEqual 'Version 2.2'

it 'should handle empty GPSVersionID', ->
@exif._dataView = getDataView '\x00\x00\x00\x01\x00\x00\x00\x01\x00'
expect(@exif._readTag('gps', 0).description).toEqual 'Unknown'

it 'should report correct description for GPSLatitudeRef', ->
@exif._dataView = getDataView '\x00\x01\x00\x02\x00\x00\x00\x02N\x00\x00\x00'
expect(@exif._readTag('gps', 0).description).toEqual 'North latitude'
Expand Down Expand Up @@ -707,6 +724,10 @@ describe 'ExifReader', ->
@exif._dataView = getDataView '\x00\x1b\x00\x07\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00'
expect(@exif._readTag('gps', 0).description).toEqual '[Undefined encoding]'

it 'should handle empty GPSProcessingMethod', ->
@exif._dataView = getDataView '\x00\x1b\x00\x07\x00\x00\x00\x01\x00'
expect(@exif._readTag('gps', 0).description).toEqual 'Undefined'

it 'should report correct text for ASCII GPSAreaInformation', ->
@exif._dataView = getDataView '\x00\x1c\x00\x07\x00\x00\x00\x0b\x00\x00\x00\x0cASCII\x00\x00\x00ABC'
expect(@exif._readTag('gps', 0).description).toEqual 'ABC'
Expand All @@ -718,3 +739,7 @@ describe 'ExifReader', ->
expect(@exif._readTag('gps', 0).description).toEqual '[Unicode encoded text]'
@exif._dataView = getDataView '\x00\x1c\x00\x07\x00\x00\x00\x08\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00'
expect(@exif._readTag('gps', 0).description).toEqual '[Undefined encoding]'

it 'should handle empty GPSAreaInformation', ->
@exif._dataView = getDataView '\x00\x1c\x00\x07\x00\x00\x00\x01\x00'
expect(@exif._readTag('gps', 0).description).toEqual 'Undefined'
35 changes: 22 additions & 13 deletions src/ExifReader.coffee
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
###
# ExifReader 1.1.0
# ExifReader 1.1.1
# http://github.com/mattiasw/exifreader
# Copyright (C) 2011-2013 Mattias Wallander <mattias@wallander.eu>
# Copyright (C) 2011-2014 Mattias Wallander <mattias@wallander.eu>
# Licensed under the GNU Lesser General Public License version 3 or later
# See license text at http://www.gnu.org/licenses/lgpl.txt
###
Expand Down Expand Up @@ -127,13 +127,16 @@ class (exports ? this).ExifReader
offset += 2
for fieldIndex in [0...numberOfFields]
tag = @_readTag(ifdType, offset)
@_tags[tag.name] = {'value': tag.value, 'description': tag.description}
if tag != undefined
@_tags[tag.name] = {'value': tag.value, 'description': tag.description}
offset += 12

_readTag: (ifdType, offset) ->
tagCode = @_getShortAt offset
tagType = @_getShortAt(offset + 2)
tagCount = @_getLongAt(offset + 4)
if @_typeSizes[tagType] == undefined
return undefined
if @_typeSizes[tagType] * tagCount <= 4
# If the value itself fits in four bytes, it is recorded instead of just
# the offset.
Expand Down Expand Up @@ -663,18 +666,24 @@ class (exports ? this).ExifReader
}
0x001a: 'GPSDestDistance',
0x001b: {'name': 'GPSProcessingMethod', 'description': (value) ->
switch value[0...8].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'ASCII\x00\x00\x00' then value[8...value.length].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'JIS\x00\x00\x00\x00\x00' then '[JIS encoded text]'
when 'UNICODE\x00' then '[Unicode encoded text]'
when '\x00\x00\x00\x00\x00\x00\x00\x00' then '[Undefined encoding]'
if value == 0
'Undefined'
else
switch value[0...8].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'ASCII\x00\x00\x00' then value[8...value.length].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'JIS\x00\x00\x00\x00\x00' then '[JIS encoded text]'
when 'UNICODE\x00' then '[Unicode encoded text]'
when '\x00\x00\x00\x00\x00\x00\x00\x00' then '[Undefined encoding]'
}
0x001c: {'name': 'GPSAreaInformation', 'description': (value) ->
switch value[0...8].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'ASCII\x00\x00\x00' then value[8...value.length].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'JIS\x00\x00\x00\x00\x00' then '[JIS encoded text]'
when 'UNICODE\x00' then '[Unicode encoded text]'
when '\x00\x00\x00\x00\x00\x00\x00\x00' then '[Undefined encoding]'
if value == 0
'Undefined'
else
switch value[0...8].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'ASCII\x00\x00\x00' then value[8...value.length].map((charCode) -> String.fromCharCode(charCode)).join ''
when 'JIS\x00\x00\x00\x00\x00' then '[JIS encoded text]'
when 'UNICODE\x00' then '[Unicode encoded text]'
when '\x00\x00\x00\x00\x00\x00\x00\x00' then '[Undefined encoding]'
}
0x001d: 'GPSDateStamp',
0x001e: {'name': 'GPSDifferential', 'description': (value) ->
Expand Down

0 comments on commit 84ddc9f

Please sign in to comment.