diff --git a/cpp/src/arrow/io/file.cc b/cpp/src/arrow/io/file.cc index c4c797c2f41..b2b880159fb 100644 --- a/cpp/src/arrow/io/file.cc +++ b/cpp/src/arrow/io/file.cc @@ -117,6 +117,10 @@ namespace io { // ---------------------------------------------------------------------- // Cross-platform file compatability layer +#if defined(_MSC_VER) +constexpr const char* kRangeExceptionError = + "Range exception during wide-char string conversion"; +#endif static inline Status CheckOpenResult( int ret, int errno_actual, const char* filename, size_t filename_length) { @@ -131,8 +135,10 @@ static inline Status CheckOpenResult( std::wstring_convert, wchar_t> converter; std::wstring wide_string( reinterpret_cast(filename), filename_length / sizeof(wchar_t)); - std::string byte_string = converter.to_bytes(wide_string); - ss << byte_string; + try { + std::string byte_string = converter.to_bytes(wide_string); + ss << byte_string; + } catch (const std::range_error&) { ss << kRangeExceptionError; } #else ss << filename; #endif @@ -162,7 +168,9 @@ static inline Status ConvertToUtf16(const std::string& input, std::wstring* resu } std::wstring_convert> utf16_converter; - *result = utf16_converter.from_bytes(input); + try { + *result = utf16_converter.from_bytes(input); + } catch (const std::range_error&) { return Status::Invalid(kRangeExceptionError); } return Status::OK(); } #endif diff --git a/cpp/src/arrow/io/io-file-test.cc b/cpp/src/arrow/io/io-file-test.cc index 3450bae13bc..1b7e052d651 100644 --- a/cpp/src/arrow/io/io-file-test.cc +++ b/cpp/src/arrow/io/io-file-test.cc @@ -96,6 +96,18 @@ class TestFileOutputStream : public FileTestFixture { std::shared_ptr file_; }; +#if defined(_MSC_VER) +TEST_F(TestFileOutputStream, FileNameWideCharConversionRangeException) { + std::shared_ptr file; + // Form literal string with non-ASCII symbol(127 + 1) + std::string file_name = "\x80"; + ASSERT_RAISES(Invalid, FileOutputStream::Open(file_name, &file)); + + std::shared_ptr rd_file; + ASSERT_RAISES(Invalid, ReadableFile::Open(file_name, &rd_file)); +} +#endif + TEST_F(TestFileOutputStream, DestructorClosesFile) { int fd; {