From: Eric Biggers Date: Thu, 21 Mar 2013 02:07:02 +0000 (-0500) Subject: Fix glob() X-Git-Tag: v1.3.0~4 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=de12c346dc64404821d52d545e2e1b3d44230f2a Fix glob() --- diff --git a/configure.ac b/configure.ac index e30d4554..06a75400 100644 --- a/configure.ac +++ b/configure.ac @@ -157,10 +157,9 @@ if test "x$ENABLE_MULTITHREADED_COMPRESSION" = "xyes"; then AC_DEFINE([ENABLE_MULTITHREADED_COMPRESSION], [1], [Define to 1 if including support for multithreaded compression]) - PTHREAD_LDADD="-lpthread" -else - PTHREAD_LDADD="" fi + +PTHREAD_LDADD="-lpthread" AC_SUBST([PTHREAD_LDADD], [$PTHREAD_LDADD]) WITH_NTFS_3G_DEFAULT="yes" diff --git a/programs/imagex-win32.c b/programs/imagex-win32.c index 3dc51d98..16648500 100644 --- a/programs/imagex-win32.c +++ b/programs/imagex-win32.c @@ -25,6 +25,20 @@ int glob(const char *pattern, int flags, int ret; size_t nspaces; + const char *backslash, *forward_slash, *end_slash; + size_t prefix_len; + + backslash = strrchr(pattern, '\\'); + end_slash = strrchr(pattern, '/'); + + if (backslash > end_slash) + end_slash = backslash; + + if (end_slash) + prefix_len = end_slash - pattern + 1; + else + prefix_len = 0; + /* This function does not support all functionality of the POSIX glob(), * so make sure the parameters are consistent with supported * functionality. */ @@ -49,7 +63,7 @@ int glob(const char *pattern, int flags, pglob->gl_pathv = NULL; nspaces = 0; do { - char *filename; + char *path; if (pglob->gl_pathc == nspaces) { size_t new_nspaces; char **pathv; @@ -62,10 +76,16 @@ int glob(const char *pattern, int flags, pglob->gl_pathv = pathv; nspaces = new_nspaces; } - filename = strdup(dat.cFileName); - if (!filename) + size_t filename_len = strlen(dat.cFileName); + size_t len_needed = prefix_len + filename_len; + + path = malloc(len_needed + 1); + if (!path) goto oom; - pglob->gl_pathv[pglob->gl_pathc++] = filename; + + memcpy(path, pattern, prefix_len); + memcpy(path + prefix_len, dat.cFileName, filename_len + 1); + pglob->gl_pathv[pglob->gl_pathc++] = path; } while (FindNextFileA(hFind, &dat)); err = GetLastError(); CloseHandle(hFind); @@ -93,7 +113,7 @@ void globfree(glob_t *pglob) size_t i; for (i = 0; i < pglob->gl_pathc; i++) free(pglob->gl_pathv[i]); - free(pglob->gl_pathv[i]); + free(pglob->gl_pathv); } static bool diff --git a/programs/imagex.c b/programs/imagex.c index c8fa94af..0f65ae51 100644 --- a/programs/imagex.c +++ b/programs/imagex.c @@ -2138,8 +2138,7 @@ int main(int argc, char **argv) /* The user may like to see more informative error messages. */ wimlib_set_print_errors(true); - /* Calling wimlib_global_init() is not strictly necessary because - * 'imagex' is single-threaded. */ + /* Do any initializations that the library needs */ ret = wimlib_global_init(); if (ret) goto out; @@ -2178,8 +2177,9 @@ out: if (ret == WIMLIB_ERR_NTFS_3G && errno != 0) imagex_error_with_errno("errno"); } - /* Calling wimlib_global_cleanup() is not strictly necessary because the - * process is exiting anyway. */ + + /* Make the library free any resources it's holding (not strictly + * necessary because the process is ending anyway). */ wimlib_global_cleanup(); return ret; } diff --git a/src/encoding.c b/src/encoding.c index aa8f9281..48bad187 100644 --- a/src/encoding.c +++ b/src/encoding.c @@ -1,7 +1,7 @@ /* * encoding.c: Convert "multibyte" strings (the locale-default encoding--- * generally, UTF-8 or something like ISO-8859-1) to UTF-16LE strings, and vice - * versa. + * versa. Also, convert UTF-8 strings to multibyte strings. */ /* @@ -23,17 +23,21 @@ * along with wimlib; if not, see http://www.gnu.org/licenses/. */ -#include "config.h" #include "wimlib_internal.h" -#include -#include "list.h" +#include #include +#include #include -#include bool wimlib_mbs_is_utf8 = true; +/* List of iconv_t conversion descriptors for a specific character conversion. + * The idea is that it is not thread-safe to have just one conversion + * descriptor, but it also is inefficient to open a new conversion descriptor to + * convert every string. Both these problems can be solved by maintaining a + * list of conversion descriptors; then, a thread can use an existing conversion + * descriptor if available. */ struct iconv_list_head { const char *from_encoding; const char *to_encoding; @@ -166,7 +170,11 @@ varname1##_to_##varname2##_buf(const chartype1 *in, size_t in_nbytes, \ \ len = iconv(*cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); \ if (len == (size_t)-1) { \ - err_msg; \ + if (!error_message_being_printed) { \ + error_message_being_printed = true; \ + err_msg; \ + error_message_being_printed = false; \ + } \ ret = err_return; \ } else { \ out[(LARGE_NUMBER-outbytesleft)/sizeof(chartype2)] = 0; \ @@ -210,23 +218,28 @@ DEFINE_CHAR_CONVERSION_FUNCTIONS(utf16le, "UTF-16LE", utf16lechar, mbs, "", mbchar, in_nbytes / 2 * MB_CUR_MAX, WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE, - ERROR_WITH_ERRNO("Failed to convert UTF-16LE " - "string %U to multibyte string", in)) + ERROR("Failed to convert UTF-16LE string " + "to multibyte string!"); + ERROR("This may be because the UTF-16LE data " + "could not be represented in your " + "locale's character encoding.")) DEFINE_CHAR_CONVERSION_FUNCTIONS(mbs, "", mbchar, utf16le, "UTF-16LE", utf16lechar, in_nbytes * 2, WIMLIB_ERR_INVALID_MULTIBYTE_STRING, ERROR_WITH_ERRNO("Failed to convert multibyte " - "string %s to UTF-16LE string", in)) + "string \"%s\" to UTF-16LE string!", in); + ERROR("If the data you provided was UTF-8, please make sure " + "the character encoding of your current locale is UTF-8.")) DEFINE_CHAR_CONVERSION_FUNCTIONS(utf8, "UTF-8", utf8char, mbs, "", mbchar, in_nbytes, - WIMLIB_ERR_INVALID_UTF8_STRING, - ERROR_WITH_ERRNO("Failed to convert UTF-8 " - "string %U to multibyte string", in)) - + WIMLIB_ERR_UNICODE_STRING_NOT_REPRESENTABLE, + ERROR("Failed to convert UTF-8 string to multibyte string!"); + ERROR("This may be because the UTF-8 data could not be represented " + "in your locale's character encoding.")) static void iconv_cleanup(struct iconv_list_head *head) @@ -250,8 +263,6 @@ iconv_global_cleanup() iconv_cleanup(&iconv_utf8_to_mbs); } - - bool utf8_str_contains_nonascii_chars(const utf8char *utf8_str) { diff --git a/src/util.c b/src/util.c index 20bff959..c0244ba2 100644 --- a/src/util.c +++ b/src/util.c @@ -92,7 +92,7 @@ special: &mbs, &mbs_nbytes); } if (ret) { - ret = fprintf(fp, "???CONVERSION FAILURE???"); + ret = fprintf(fp, "??????"); } else { ret = fprintf(fp, "%s", mbs); FREE(mbs); diff --git a/src/util.h b/src/util.h index 4fd117df..28f9655f 100644 --- a/src/util.h +++ b/src/util.h @@ -52,9 +52,10 @@ typedef uint64_t u64; /* A pointer to 'mbchar' indicates a string of "multibyte characters" provided * in the default encoding of the user's locale, which may be "UTF-8", * "ISO-8859-1", "C", or any other ASCII-compatible encoding. - * "ASCII-compatible" here means any encoding where all ASCII characters have - * the same representation, and any non-ASCII character is represented as a - * sequence of one or more bytes not already used by any ASCII character. */ + * "ASCII-compatible" here means any encoding where all ASCII-representable + * characters have the same representation as in ASCII itself, and any non-ASCII + * character is represented as a sequence of one or more bytes not already used + * by any ASCII character. */ typedef char mbchar; /* A pointer to 'utf8char' indicates a UTF-8 encoded string */