Fix seg fault when using `iconv_open()` (#2403)

* Fix seg fault when using `iconv_open()`

- Fix failure condition for `iconv_open()`
- Add new exception when failing to change the text encoding of an
Exif comment

* Add testing for `iconv_open()` seg fault bug

* Fix Python test by changing log level
main
Peter 3 years ago committed by GitHub
parent dc5dc0d2e3
commit 1f364be1fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -223,6 +223,7 @@ enum class ErrorCode {
kerCorruptedMetadata,
kerArithmeticOverflow,
kerMallocFailed,
kerInvalidIconvEncoding,
kerErrorCount,
};

@ -589,7 +589,13 @@ void Converter::cnvExifComment(const char* from, const char* to) {
return;
}
// Todo: Convert to UTF-8 if necessary
(*xmpData_)[to] = cv->comment();
try {
(*xmpData_)[to] = cv->comment();
} catch (const Error&) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
#endif
}
if (erase_)
exifData_->erase(pos);
}
@ -1567,7 +1573,7 @@ bool convertStringCharsetIconv(std::string& str, const char* from, const char* t
bool ret = true;
iconv_t cd;
cd = iconv_open(to, from);
if (!cd) {
if (cd == (iconv_t)(-1)) {
#ifndef SUPPRESS_WARNINGS
EXV_WARNING << "iconv_open: " << strError() << "\n";
#endif

@ -89,6 +89,7 @@ constexpr std::array errList{
N_("corrupted image metadata"), // kerCorruptedMetadata
N_("Arithmetic operation overflow"), // kerArithmeticOverflow
N_("Memory allocation failed"), // kerMallocFailed
N_("Cannot convert text encoding from '%1' to '%2'"), // kerInvalidIconvEncoding
};
static_assert(errList.size() == static_cast<size_t>(Exiv2::ErrorCode::kerErrorCount),
"errList needs to contain a error msg for every ErrorCode defined in error.hpp");

@ -370,10 +370,11 @@ size_t CommentValue::copy(byte* buf, ByteOrder byteOrder) const {
std::ostream& CommentValue::write(std::ostream& os) const {
CharsetId csId = charsetId();
std::string text = comment();
if (csId != undefined) {
os << "charset=" << CharsetInfo::name(csId) << " ";
}
return os << comment();
return os << text;
}
std::string CommentValue::comment(const char* encoding) const {
@ -384,7 +385,8 @@ std::string CommentValue::comment(const char* encoding) const {
c = value_.substr(8);
if (charsetId() == unicode) {
const char* from = !encoding || *encoding == '\0' ? detectCharset(c) : encoding;
convertStringCharset(c, from, "UTF-8");
if (!convertStringCharset(c, from, "UTF-8"))
throw Error(ErrorCode::kerInvalidIconvEncoding, encoding, "UTF-8");
}
bool bAscii = charsetId() == undefined || charsetId() == ascii;
// # 1266 Remove trailing nulls

Binary file not shown.

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from system_tests import CaseMeta, CopyTmpFiles, check_no_ASAN_UBSAN_errors
@CopyTmpFiles("$data_path/issue_2403_poc.exv")
class checkIconvSegFault(metaclass=CaseMeta):
url = """"""
description = """Test the fixcom action in the exiv2 app"""
filename = """$tmp_path/issue_2403_poc.exv"""
commands = ["""$exiv2 --verbose --log e --encode made_up_encoding fixcom $filename""",
"""$exiv2 --verbose --keep --encode UCS-2LE fixcom $filename"""]
retval = [1,0]
stdout = ["""File 1/1: $filename
""",
"""File 1/1: $filename
Setting Exif UNICODE user comment to "Test"
"""]
stderr = ["""Exiv2 exception in fixcom action for file $filename:
Cannot convert text encoding from 'made_up_encoding' to 'UTF-8'
""",
""""""]

@ -147,6 +147,7 @@ def get_valid_files(data_dir):
# this test file actually contains some eixf info, but windows has
# different output let's try and fix this later
"exiv2-bug1044.tif",
"issue_2403_poc.exv",
]
file_paths = [

Loading…
Cancel
Save