From 6cd9263fa7b74ec2e57a3e191d01a8189715a09c Mon Sep 17 00:00:00 2001 From: postscript-dev <43813-postscript-dev@users.noreply.gitlab.gnome.org> Date: Sat, 6 Mar 2021 18:59:31 +0000 Subject: [PATCH] Fix langAltValue::read() parsing + Fix segmentation faults in langAlt parse + Fix mismatched quotation marks and incorrect values + Add Python testing + Some tests commented out as quotation marks are filtered, preventing them from running. Closes #1481. --- include/exiv2/error.hpp | 1 + src/error.cpp | 2 + src/value.cpp | 27 +++- tests/bugfixes/github/test_issue_1481.py | 160 +++++++++++++++++++++++ tests/suite.conf | 2 + 5 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 tests/bugfixes/github/test_issue_1481.py diff --git a/include/exiv2/error.hpp b/include/exiv2/error.hpp index 1787f10c..942a4cd5 100644 --- a/include/exiv2/error.hpp +++ b/include/exiv2/error.hpp @@ -249,6 +249,7 @@ namespace Exiv2 { kerInvalidXMP, kerTiffDirectoryTooLarge, kerInvalidTypeValue, + kerInvalidLangAltValue, kerInvalidMalloc, kerCorruptedMetadata, kerArithmeticOverflow, diff --git a/src/error.cpp b/src/error.cpp index 05d83de8..f68cc64e 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -158,6 +158,8 @@ namespace { N_("tiff directory length is too large") }, { Exiv2::kerInvalidTypeValue, N_("invalid type in tiff structure") }, + { Exiv2::kerInvalidLangAltValue, + N_("Invalid LangAlt value `%1'") }, // %1=value { Exiv2::kerInvalidMalloc, N_("invalid memory allocation request") }, { Exiv2::kerCorruptedMetadata, diff --git a/src/value.cpp b/src/value.cpp index b96f7de3..8e50a392 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -856,18 +856,39 @@ namespace Exiv2 { } int LangAltValue::read(const std::string& buf) - { + { std::string b = buf; std::string lang = "x-default"; if (buf.length() > 5 && buf.substr(0, 5) == "lang=") { + const char* ALPLHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + const char* ALPLHA_NUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + std::string::size_type pos = buf.find_first_of(' '); lang = buf.substr(5, pos-5); // Strip quotes (so you can also specify the language without quotes) - if (lang[0] == '"') lang = lang.substr(1); - if (lang[lang.length()-1] == '"') lang = lang.substr(0, lang.length()-1); + if (lang[0] == '"') { + lang = lang.substr(1); + + if (lang == "" || lang.find('"') != lang.length()-1) + throw Error(kerInvalidLangAltValue, buf); // *** + + lang = lang.substr(0, lang.length()-1); + } + + if (lang == "") throw Error(kerInvalidLangAltValue, buf); // *** + + // Check language is in the correct format (see https://www.ietf.org/rfc/rfc3066.txt) + std::string::size_type charPos = lang.find_first_not_of(ALPLHA); + if (charPos != std::string::npos) { + if (lang[charPos] != '-' || lang.find_first_not_of(ALPLHA_NUM, charPos+1) != std::string::npos) + throw Error(kerInvalidLangAltValue, buf); + } + b.clear(); if (pos != std::string::npos) b = buf.substr(pos+1); } + + value_[lang] = b; return 0; } diff --git a/tests/bugfixes/github/test_issue_1481.py b/tests/bugfixes/github/test_issue_1481.py new file mode 100644 index 00000000..fe941346 --- /dev/null +++ b/tests/bugfixes/github/test_issue_1481.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- + +import system_tests + +@system_tests.CopyFiles("$data_path/exiv2-empty.jpg") +class CheckXmpLangAltValues(metaclass=system_tests.CaseMeta): + + url = "https://github.com/Exiv2/exiv2/issues/1481" + +# Python unittest is filtering out empty pairs of "" and flags up an error if +# a mismatched number of quotes is used inside the commands[] (see +# https://docs.python.org/3/library/shlex.html#parsing-rules). +# +# This means that some of the tests in the github issue cannot be run. + + langAltValue = [ + # 1. No language value + """lang= test1-1""", + """lang=\" test1-2""", + + # 2. Empty language value + """lang=\"\" test2""", + + # 3. Mismatched and/or incorrect positioning of quotation marks + """lang=\"\"test3-1""", + """lang=\"test3-2""", + """lang=\"en-UK test3-3""", + """lang=en-US\" test3-4""", + """lang=test3-5\"""", + """lang=test3-6\"\"""", + + # 4. Invalid characters in language part + """lang=en-UK- test4-1""", + """lang=en=UK test4-2""", + ] + + filename = system_tests.path("$data_path/exiv2-empty_copy.jpg") + + commands = [ + # 1. No language value + """$exiv2 -M"set Xmp.dc.title """ + langAltValue[0] + """" $filename""", +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[1] + """" $filename""", + """$exiv2 -px $filename""", + + # 2. Empty language value +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[2] + """" $filename""", +# """$exiv2 -px $filename""", + + # 3. Mismatched and/or incorrect positioning of quotation marks +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[3] + """" $filename""", +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[4] + """" $filename""", +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[5] + """" $filename""", +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[6] + """" $filename""", +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[7] + """" $filename""", +# """$exiv2 -M"set Xmp.dc.title """ + langAltValue[8] + """" $filename""", +# """$exiv2 -px $filename""", + + # 4. Invalid characters in language part + """$exiv2 -M"set Xmp.dc.title """ + langAltValue[9] + """" $filename""", + """$exiv2 -M"set Xmp.dc.title """ + langAltValue[10] + """" $filename""", + """$exiv2 -px $filename""" + ] + + stdout = [ + # 1. No language value + "", +# "", + "", + + # 2. Empty language value +# "", +# "", + + # 3. Mismatched and/or incorrect positioning of quotation marks +# "", +# "", +# "", +# "", +# "", +# "", +# "", + + # 4. Invalid characters in language part + "", + "", + "" + ] + + stderr = [ + # 1. No language value + """$exiv2_modify_exception_message $filename: +$kerInvalidLangAltValue `""" + langAltValue[0] + """' +""", +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[1] + """' +# """, + "", + + # 2. Empty language value +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[2] + """' +# """, +# "", + + # 3. Mismatched and/or incorrect positioning of quotation marks +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[3] + """' +# """, +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[4] + """' +# """, +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[5] + """' +# """, +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[6] + """' +# """, +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[7] + """' +# """, +# """$exiv2_modify_exception_message $filename: +# $kerInvalidLangAltValue `""" + langAltValue[8] + """' +# """, +# "", + + # 4. Invalid characters in language part + """$exiv2_modify_exception_message $filename: +$kerInvalidLangAltValue `""" + langAltValue[9] + """' +""", + """$exiv2_modify_exception_message $filename: +$kerInvalidLangAltValue `""" + langAltValue[10] + """' +""", + "" + ] + + retval = [ + # 1. No language value + 1, +# 1, + 0, + + # 2. Empty language value +# 1, +# 0, + + # 3. Mismatched and/or incorrect positioning of quotation marks +# 1, +# 1, +# 1, +# 1, +# 1, +# 1, +# 0, + + # 4. Invalid characters in language part + 1, + 1, + 0 + ] + diff --git a/tests/suite.conf b/tests/suite.conf index e5c48c21..4af1af1b 100644 --- a/tests/suite.conf +++ b/tests/suite.conf @@ -42,8 +42,10 @@ kerInvalidTypeValue: invalid type in tiff structure kerNotAJpeg : This does not look like a JPEG image kerNoImageInInputData: Input data does not contain a valid image kerFileContainsUnknownImageType: The file contains data of an unknown image type +kerInvalidLangAltValue: Invalid LangAlt value addition_overflow_message: Overflow in addition exiv2_exception_message: Exiv2 exception in print action for file +exiv2_modify_exception_message: Exiv2 exception in modify action for file exiv2_overflow_exception_message: std::overflow_error exception in print action for file exception_in_extract: Exiv2 exception in extract action for file uncaught_exception: Uncaught exception: