Advertisement
Guest User

gpgme fix for windows unicode paths

a guest
Apr 8th, 2019
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.29 KB | None | 0 0
  1. diff --git a/src/dirinfo.c b/src/dirinfo.c
  2. index d4811990..d3abead1 100644
  3. --- a/src/dirinfo.c
  4. +++ b/src/dirinfo.c
  5. @@ -260,7 +260,7 @@ get_gpgconf_item (int what)
  6.        char *pgmname;
  7.  
  8.        pgmname = dirinfo.disable_gpgconf? NULL : _gpgme_get_gpgconf_path ();
  9. -      if (pgmname && access (pgmname, F_OK))
  10. +      if (pgmname && win_access (pgmname, F_OK))
  11.          {
  12.            _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
  13.                          "gpgme-dinfo: gpgconf='%s' [not installed]\n", pgmname);
  14. diff --git a/src/w32-io.c b/src/w32-io.c
  15. index 919ca6fd..a7535433 100644
  16. --- a/src/w32-io.c
  17. +++ b/src/w32-io.c
  18. @@ -1476,8 +1476,13 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
  19.        free (tmp_name);
  20.        return TRACE_SYSRES (-1);
  21.      }
  22. -  if (!CreateProcessA (spawnhelper,
  23. -              arg_string,
  24. +
  25. +  wchar_t *Utf8ToUtf16(const char *utf8);
  26. +
  27. +  wchar_t *sh = Utf8ToUtf16(spawnhelper);
  28. +  wchar_t *a = Utf8ToUtf16(arg_string);
  29. +  if (!CreateProcessW (sh,
  30. +              a,
  31.                &sec_attr,     /* process security attributes */
  32.                &sec_attr,     /* thread security attributes */
  33.                FALSE,         /* inherit handles */
  34. @@ -1490,6 +1495,8 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
  35.        int lasterr = (int)GetLastError ();
  36.        TRACE_LOG  ("CreateProcess failed: ec=%d", lasterr);
  37.        free (arg_string);
  38. +      free (sh);
  39. +      free (a);
  40.        close (tmp_fd);
  41.        DeleteFileA (tmp_name);
  42.        free (tmp_name);
  43. @@ -1498,6 +1505,8 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
  44.        gpg_err_set_errno (EIO);
  45.        return TRACE_SYSRES (-1);
  46.      }
  47. +  free (sh);
  48. +  free (a);
  49.  
  50.    if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
  51.      _gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId);
  52. diff --git a/src/w32-util.c b/src/w32-util.c
  53. index 9802d9cc..eff7eeb0 100644
  54. --- a/src/w32-util.c
  55. +++ b/src/w32-util.c
  56. @@ -386,6 +386,107 @@ _gpgme_get_inst_dir (void)
  57.  }
  58.  
  59.  
  60. +wchar_t *Utf8ToUtf16(const char *utf8)
  61. +{
  62. +    size_t len = strlen(utf8);
  63. +
  64. +    // "Code page" value used with MultiByteToWideChar() for UTF-8 conversion
  65. +    const UINT codePageUtf8 = CP_UTF8;
  66. +
  67. +    // Safely fails if an invalid UTF-8 character is encountered
  68. +    const DWORD flags = MB_ERR_INVALID_CHARS;
  69. +
  70. +    // Get the length, in WCHARs, of the resulting UTF-16 string
  71. +    const int utf16Length = MultiByteToWideChar(
  72. +        codePageUtf8,       // source string is in UTF-8
  73. +        flags,              // conversion flags
  74. +        utf8,   // source UTF-8 string
  75. +        len,   // length of source UTF-8 string, in chars
  76. +        0,            // unused - no conversion done in this step
  77. +        0);                 // request size of destination buffer, in WCHARs
  78. +    if (utf16Length == 0)
  79. +    {
  80. +        // Conversion error
  81. +        return 0;
  82. +    }
  83. +
  84. +    wchar_t *utf16 = (wchar_t*)malloc((utf16Length + 1) * sizeof(wchar_t));
  85. +    memset(utf16, 0, (utf16Length + 1) * sizeof(wchar_t));
  86. +
  87. +    // Do the conversion from UTF-8 to UTF-16
  88. +    int result = MultiByteToWideChar(
  89. +        codePageUtf8,       // source string is in UTF-8
  90. +        flags,              // conversion flags
  91. +        utf8,   // source UTF-8 string
  92. +        len,   // length of source UTF-8 string, in chars
  93. +        utf16,        // pointer to destination buffer
  94. +        utf16Length);       // size of destination buffer, in WCHARs
  95. +    if (result == 0)
  96. +    {
  97. +        // Conversion error
  98. +        return 0;
  99. +    }
  100. +
  101. +    return utf16;
  102. +}
  103. +
  104. +char *Utf16ToUtf8(const wchar_t *utf16)
  105. +{
  106. +    size_t len = wcslen(utf16);
  107. +
  108. +    // "Code page" value used with WideCharToMultiByte() for UTF-8 conversion
  109. +    const UINT codePageUtf8 = CP_UTF8;
  110. +
  111. +    // Safely fails if an invalid UTF-16 character is encountered
  112. +    const DWORD flags = WC_ERR_INVALID_CHARS;
  113. +
  114. +    // Get the length, in chars, of the resulting UTF-8 string
  115. +    const int utf8Length = WideCharToMultiByte(
  116. +        codePageUtf8,       // convert to UTF-8
  117. +        flags,              // conversion flags
  118. +        utf16,  // source UTF-16 string
  119. +        len,  // length of source UTF-16 string, in WCHARs
  120. +        0,            // unused - no conversion required in this step
  121. +        0,                  // request size of destination buffer, in chars
  122. +        0, 0);  // unused
  123. +    if (utf8Length == 0)
  124. +    {
  125. +        // Conversion error
  126. +        return 0;
  127. +    }
  128. +
  129. +    char *utf8 = (char*)malloc(utf8Length + 1);
  130. +    utf8[utf8Length] = 0;
  131. +
  132. +    // Do the conversion from UTF-16 to UTF-8
  133. +    int result = WideCharToMultiByte(
  134. +        codePageUtf8,       // convert to UTF-8
  135. +        flags,              // conversion flags
  136. +        utf16,  // source UTF-16 string
  137. +        len,  // length of source UTF-16 string, in WCHARs
  138. +        utf8,         // pointer to destination buffer
  139. +        utf8Length,         // size of destination buffer, in chars
  140. +        0, 0);  // unused
  141. +    if (result == 0)
  142. +    {
  143. +        // Conversion error
  144. +        return 0;
  145. +    }
  146. +    return utf8;
  147. +}
  148. +
  149. +int win_access(
  150. +    const char *path,
  151. +    int mode
  152. +)
  153. +{
  154. +    wchar_t *u16 = Utf8ToUtf16(path);
  155. +
  156. +    int r = _waccess(u16, F_OK);
  157. +    free(u16);
  158. +    return r;
  159. +}
  160. +
  161.  static char *
  162.  find_program_in_dir (const char *dir, const char *name)
  163.  {
  164. @@ -395,7 +496,7 @@ find_program_in_dir (const char *dir, const char *name)
  165.    if (!result)
  166.      return NULL;
  167.  
  168. -  if (access (result, F_OK))
  169. +  if (win_access (result, F_OK))
  170.      {
  171.        free (result);
  172.        return NULL;
  173. @@ -419,7 +520,7 @@ find_program_at_standard_place (const char *name)
  174.    if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0))
  175.      {
  176.        result = _gpgme_strconcat (path, "\\", name, NULL);
  177. -      if (result && access (result, F_OK))
  178. +      if (result && win_access (result, F_OK))
  179.          {
  180.            free (result);
  181.            result = NULL;
  182. @@ -429,7 +530,7 @@ find_program_at_standard_place (const char *name)
  183.        && SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
  184.      {
  185.        result = _gpgme_strconcat (path, "\\", name, NULL);
  186. -      if (result && access (result, F_OK))
  187. +      if (result && win_access (result, F_OK))
  188.          {
  189.            free (result);
  190.            result = NULL;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement