summaryrefslogtreecommitdiff
path: root/libs/pbd/test
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-07-25 16:33:54 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-07-25 23:14:45 +1000
commitdfe2ac1d385e8fe9ddef1c3eb8db0397c24da151 (patch)
tree74118662c671d33c61d3196d9749297908a5b5a2 /libs/pbd/test
parent545fd78a141ce010704a367a61355fe5f710efce (diff)
Add unit test to assert that using locale_from_utf8/::open will fail for some file paths on Windows
Diffstat (limited to 'libs/pbd/test')
-rw-r--r--libs/pbd/test/filesystem_test.cc102
-rw-r--r--libs/pbd/test/filesystem_test.h2
2 files changed, 104 insertions, 0 deletions
diff --git a/libs/pbd/test/filesystem_test.cc b/libs/pbd/test/filesystem_test.cc
index 2c2de94d02..b7a86d260c 100644
--- a/libs/pbd/test/filesystem_test.cc
+++ b/libs/pbd/test/filesystem_test.cc
@@ -6,8 +6,11 @@
#include <unistd.h>
#include <stdlib.h>
+#include <fcntl.h>
+
#include <glibmm/miscutils.h>
#include <glibmm/fileutils.h>
+#include <glibmm/convert.h>
#include "pbd/file_utils.h"
#include "pbd/pathexpand.h"
@@ -119,6 +122,105 @@ FilesystemTest::testCopyFileUTF8Filename ()
}
void
+FilesystemTest::testOpenFileUTF8Filename ()
+{
+ vector<string> i18n_files;
+
+ Searchpath i18n_path (test_search_path ());
+ i18n_path.add_subdirectory_to_paths ("i18n_test");
+
+ PBD::find_files_matching_pattern (i18n_files, i18n_path, "*.tst");
+
+ CPPUNIT_ASSERT (i18n_files.size () == 8);
+
+ cerr << endl;
+ cerr << "Opening " << i18n_files.size ()
+ << " test files from: " << i18n_path.to_string () << endl;
+
+ // check that g_open will successfully open all the test files
+ for (vector<string>::iterator i = i18n_files.begin (); i != i18n_files.end ();
+ ++i) {
+ string input_path = *i;
+
+ cerr << "Opening file: " << input_path << " with g_open" << endl;
+
+ int fdgo = g_open (input_path.c_str(), O_RDONLY, 0444);
+
+ CPPUNIT_ASSERT (fdgo != -1);
+
+ if (fdgo >= 0) {
+ ::close (fdgo);
+ }
+ }
+
+#ifdef PLATFORM_WINDOWS
+ // This test is here to prove and remind us that using Glib::locale_from_utf8
+ // to convert a utf-8 encoded file path for use with ::open will not work
+ // for all file paths.
+ //
+ // It may be possible to convert a string that is utf-8 encoded that will not
+ // work with ::open(on windows) to a string that will work with ::open using
+ // Glib::locale_from_utf8 string if all the characters that are contained
+ // in the utf-8 string can be found/mapped in the system code page.
+ //
+ // European locales that only have a small amount of extra characters with
+ // accents/umlauts I'm guessing will be more likely succeed but CJK locales
+ // will almost certainly fail
+
+ bool conversion_failed = false;
+
+ for (vector<string>::iterator i = i18n_files.begin (); i != i18n_files.end ();
+ ++i) {
+ string input_path = *i;
+ cerr << "Opening file: " << input_path << " with locale_from_utf8 and ::open "
+ << endl;
+ string converted_input_path;
+ int fdo;
+
+ try {
+ // this will fail for utf8 that contains characters that aren't
+ // representable in the system code page
+ converted_input_path = Glib::locale_from_utf8 (input_path);
+ // conversion succeeded so we expect ::open to be successful if the
+ // current C library locale is the same as the system locale, which
+ // it should be as we haven't changed it.
+ fdo = ::open (converted_input_path.c_str (), O_RDONLY, 0444);
+ CPPUNIT_ASSERT (fdo != -1);
+
+ if (converted_input_path != input_path) {
+ cerr << "Character set conversion succeeded and strings differ for input "
+ "string: " << input_path << endl;
+ // file path must have contained non-ASCII characters that were mapped
+ // from the system code page so we would expect the original
+ // utf-8 file path to fail with ::open
+ int fd2 = ::open (input_path.c_str (), O_RDONLY, 0444);
+ CPPUNIT_ASSERT (fd2 == -1);
+ }
+
+ } catch (const Glib::ConvertError& err) {
+ cerr << "Character set conversion failed: " << err.what () << endl;
+ // I am confident that on Windows with the test data that no locale will
+ // have a system code page containing all the characters required
+ // and conversion will fail for at least one of the filenames
+ conversion_failed = true;
+ // CPPUNIT_ASSERT (err.code() == ?);
+
+ // conversion failed so we expect the original utf-8 string to fail
+ // with ::open on Windows as the file path will not exist
+ fdo = ::open (input_path.c_str (), O_RDONLY, 0444);
+ CPPUNIT_ASSERT (fdo == -1);
+ }
+
+ if (fdo >= 0) {
+ ::close (fdo);
+ }
+ }
+ // we expect at least one conversion failure with the filename test data
+ CPPUNIT_ASSERT (conversion_failed);
+#endif
+}
+
+void
FilesystemTest::testFindFilesMatchingPattern ()
{
vector<string> patch_files;
diff --git a/libs/pbd/test/filesystem_test.h b/libs/pbd/test/filesystem_test.h
index 180149dd36..c200bb2ba7 100644
--- a/libs/pbd/test/filesystem_test.h
+++ b/libs/pbd/test/filesystem_test.h
@@ -7,6 +7,7 @@ class FilesystemTest : public CppUnit::TestFixture
CPPUNIT_TEST (testPathIsWithin);
CPPUNIT_TEST (testCopyFileASCIIFilename);
CPPUNIT_TEST (testCopyFileUTF8Filename);
+ CPPUNIT_TEST (testOpenFileUTF8Filename);
CPPUNIT_TEST (testFindFilesMatchingPattern);
CPPUNIT_TEST (testClearDirectory);
CPPUNIT_TEST (testRemoveDirectory);
@@ -17,6 +18,7 @@ public:
void testPathIsWithin ();
void testCopyFileASCIIFilename ();
void testCopyFileUTF8Filename ();
+ void testOpenFileUTF8Filename ();
void testFindFilesMatchingPattern ();
void testClearDirectory ();
void testRemoveDirectory ();