diff --git a/src/fs/Charset.cxx b/src/fs/Charset.cxx index f91920819..a331bd064 100644 --- a/src/fs/Charset.cxx +++ b/src/fs/Charset.cxx @@ -114,11 +114,12 @@ PathToUTF8(PathTraitsFS::const_pointer_type path_fs) return FixSeparators(path_fs); #ifdef HAVE_FS_CHARSET - const auto buffer = fs_converter->ToUTF8(path_fs); - if (buffer.IsNull()) + try { + const auto buffer = fs_converter->ToUTF8(path_fs); + return FixSeparators(PathTraitsUTF8::string(buffer.c_str())); + } catch (const std::runtime_error &) { return PathTraitsUTF8::string(); - - return FixSeparators(PathTraitsUTF8::string(buffer.c_str())); + } #endif #endif } diff --git a/src/lib/icu/Converter.cxx b/src/lib/icu/Converter.cxx index 815697821..1b638bbfd 100644 --- a/src/lib/icu/Converter.cxx +++ b/src/lib/icu/Converter.cxx @@ -90,8 +90,11 @@ DoConvert(iconv_t conv, const char *src) size_t n = iconv(conv, &in, &in_left, &out, &out_left); - if (n == static_cast(-1) || in_left > 0) - return nullptr; + if (n == static_cast(-1)) + throw MakeErrno("Charset conversion failed"); + + if (in_left > 0) + throw std::runtime_error("Charset conversion failed"); return AllocatedString<>::Duplicate(buffer, sizeof(buffer) - out_left); } @@ -100,7 +103,7 @@ DoConvert(iconv_t conv, const char *src) AllocatedString IcuConverter::ToUTF8(const char *s) const -try { +{ #ifdef HAVE_ICU const ScopeLock protect(mutex); @@ -116,26 +119,23 @@ try { &source, source + strlen(source), nullptr, true, &code); if (code != U_ZERO_ERROR) - return nullptr; + throw std::runtime_error(FormatString("Failed to convert to Unicode: %s", + u_errorName(code)).c_str()); const size_t target_length = target - buffer; return UCharToUTF8({buffer, target_length}); #elif defined(HAVE_ICONV) return DoConvert(to_utf8, s); #endif -} catch (const std::runtime_error &) { - return nullptr; } AllocatedString IcuConverter::FromUTF8(const char *s) const -try { +{ #ifdef HAVE_ICU const ScopeLock protect(mutex); const auto u = UCharFromUTF8(s); - if (u.IsNull()) - return nullptr; ucnv_resetFromUnicode(converter); @@ -149,15 +149,14 @@ try { nullptr, true, &code); if (code != U_ZERO_ERROR) - return nullptr; + throw std::runtime_error(FormatString("Failed to convert from Unicode: %s", + u_errorName(code)).c_str()); return AllocatedString<>::Duplicate(buffer, target); #elif defined(HAVE_ICONV) return DoConvert(from_utf8, s); #endif -} catch (const std::runtime_error &) { - return nullptr; } #endif diff --git a/src/lib/icu/Converter.hxx b/src/lib/icu/Converter.hxx index 59b1e5b5a..6e20c88f9 100644 --- a/src/lib/icu/Converter.hxx +++ b/src/lib/icu/Converter.hxx @@ -79,7 +79,7 @@ public: /** * Convert the string to UTF-8. * - * Returns AllocatedString::Null() on error. + * Throws std::runtime_error on error. */ gcc_pure gcc_nonnull_all AllocatedString ToUTF8(const char *s) const; @@ -87,7 +87,7 @@ public: /** * Convert the string from UTF-8. * - * Returns AllocatedString::Null() on error. + * Throws std::runtime_error on error. */ gcc_pure gcc_nonnull_all AllocatedString FromUTF8(const char *s) const; diff --git a/test/TestIcu.cxx b/test/TestIcu.cxx index c4a015c4e..843b4c64e 100644 --- a/test/TestIcu.cxx +++ b/test/TestIcu.cxx @@ -54,8 +54,11 @@ public: CPPUNIT_ASSERT(converter != nullptr); for (const auto i : invalid_utf8) { - auto f = converter->FromUTF8(i); - CPPUNIT_ASSERT_EQUAL(true, f.IsNull()); + try { + auto f = converter->FromUTF8(i); + CPPUNIT_FAIL("Exception expected"); + } catch (const std::runtime_error &) { + } } for (const auto i : latin1_tests) {