diff options
author | yawano <yawano@chromium.org> | 2015-03-01 22:40:38 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-02 06:41:24 +0000 |
commit | b74305ac60bfc66b49fb9b5ddc407ec8c44148c0 (patch) | |
tree | 739371d4d12a0db9de7aa4157aa5b1e102c8392b | |
parent | 3cb91369e4dfa935884c0cdbfd1b664b0fe2c026 (diff) | |
download | chromium_src-b74305ac60bfc66b49fb9b5ddc407ec8c44148c0.zip chromium_src-b74305ac60bfc66b49fb9b5ddc407ec8c44148c0.tar.gz chromium_src-b74305ac60bfc66b49fb9b5ddc407ec8c44148c0.tar.bz2 |
Handle wrongly formatted EXIF string field.
BUG=462521
TEST=out/Release/browser_tests --gtest_filter=FileManagerJsTest.ExifParser
Review URL: https://codereview.chromium.org/968793002
Cr-Commit-Position: refs/heads/master@{#318654}
4 files changed, 110 insertions, 0 deletions
diff --git a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc index 415edfa..45890d0 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_jstest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_jstest.cc @@ -158,3 +158,8 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ThumbnailModel) { RunTest(base::FilePath(FILE_PATH_LITERAL( "foreground/js/metadata/thumbnail_model_unittest.html"))); } + +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ExifParser) { + RunTest(base::FilePath(FILE_PATH_LITERAL( + "foreground/js/metadata/exif_parser_unittest.html"))); +} diff --git a/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js index e70fe3b..5fb2e01 100644 --- a/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js +++ b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser.js @@ -362,6 +362,7 @@ ExifParser.prototype.readTagValue = function(br, tag) { } else { tag.value = String.fromCharCode.apply(null, tag.value); } + this.validateAndFixStringTag_(tag); break; case 3: // Short @@ -400,6 +401,23 @@ ExifParser.prototype.readTagValue = function(br, tag) { }; /** + * Validates string tag value, and fix it if necessary. + * @param {!ExifEntry} tag A tag to be validated and fixed. + * @private + */ +ExifParser.prototype.validateAndFixStringTag_ = function(tag) { + if (tag.format === 2) { // string + // String should end with null character. + if (tag.value.charAt(tag.value.length - 1) !== '\0') { + tag.value += '\0'; + tag.componentCount = tag.value.length; + this.vlog('Invalid format: 0x' + tag.id.toString(16) + '/' + tag.format + + ': Did not end with null character. Null character is appended.'); + } + } +}; + +/** * Map from the exif orientation value to the horizontal scale value. * @const * @type {Array.<number>} diff --git a/ui/file_manager/file_manager/foreground/js/metadata/exif_parser_unittest.html b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser_unittest.html new file mode 100644 index 0000000..0d96a8b --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser_unittest.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- Copyright 2015 The Chromium Authors. All rights reserved. + -- Use of this source code is governed by a BSD-style license that can be + -- found in the LICENSE file. + --> + +<script type="text/javascript"> + function importScripts(script) {} +</script> + +<script src="../../../../gallery/js/image_editor/image_encoder.js"></script> +<script src="../../../../gallery/js/image_editor/exif_encoder.js"></script> + +<script src="metadata_dispatcher.js"></script> +<script src="metadata_parser.js"></script> +<script src="byte_reader.js"></script> +<script src="exif_constants.js"></script> +<script src="exif_parser.js"></script> + +<script src="exif_parser_unittest.js"></script> diff --git a/ui/file_manager/file_manager/foreground/js/metadata/exif_parser_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser_unittest.js new file mode 100644 index 0000000..eefe242 --- /dev/null +++ b/ui/file_manager/file_manager/foreground/js/metadata/exif_parser_unittest.js @@ -0,0 +1,67 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Creates a directory with specified tag. This method only supports string + * format tag which is longer than 4 characters. + * @param {!TypedArray} bytes Bytes to be written. + * @param {!ExifEntry} tag An exif entry which will be written. + */ +function writeDirectory_(bytes, tag) { + assertEquals(2, tag.format); + assertTrue(tag.componentCount > 4); + + var byteWriter = new ByteWriter(bytes.buffer, 0); + byteWriter.writeScalar(1, 2); // Number of fields. + + byteWriter.writeScalar(tag.id, 2); + byteWriter.writeScalar(tag.format, 2); + byteWriter.writeScalar(tag.componentCount, 4); + byteWriter.forward(tag.id, 4); + + byteWriter.writeScalar(0, 4); // Offset to next IFD. + + byteWriter.resolveOffset(tag.id); + byteWriter.writeString(tag.value); + + byteWriter.checkResolved(); +} + +/** + * Parses exif data and return parsed tags. + * @param {!TypedArray} bytes Bytes to be read. + * @return {!Object<!Exif.Tag, !ExifEntry>} Tags. + */ +function parseExifData_(bytes) { + var exifParser = new ExifParser(this); + exifParser.log = function(arg) { console.log(arg); }; + exifParser.vlog = function(arg) { console.log(arg); }; + + var tags = {}; + var byteReader = new ByteReader(bytes.buffer); + assertEquals(0, exifParser.readDirectory(byteReader, tags)); + return tags; +} + +/** + * Test case a string doest not end with null character termination. + */ +function testWithoutNullCharacterTermination() { + // Create a data which doesn't end with null character. + var bytes = new Uint8Array(0x10000); + writeDirectory_(bytes, { + id: 0x10f, // Manufacture. + format: 2, // String. + componentCount: 11, + value: 'Manufacture' + }); + + // Parse the data. + var tags = parseExifData_(bytes); + + // Null character should be added at the end of value. + var manufactureTag = tags[0x10f]; + assertEquals(12, manufactureTag.componentCount); + assertEquals('Manufacture\0', manufactureTag.value); +} |