Skip to content

Commit

Permalink
[mono] win32 implementation of g_get_current_dir (dotnet#58523)
Browse files Browse the repository at this point in the history
Fix dotnet#56163

The getcwd call is returning the string encoded in system character
encoding instead of utf-8.

Use native GetCurrentDirectoryW call instead and convert to utf-8.
  • Loading branch information
radekdoulik authored Sep 2, 2021
1 parent f41b259 commit 6f68bbd
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 23 deletions.
23 changes: 0 additions & 23 deletions src/mono/mono/eglib/gfile-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,26 +161,3 @@ g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **gerror)
}
return fd;
}

gchar *
g_get_current_dir (void)
{
int s = 32;
char *buffer = NULL, *r;
gboolean fail;

do {
buffer = g_realloc (buffer, s);
r = getcwd (buffer, s);
fail = (r == NULL && errno == ERANGE);
if (fail) {
s <<= 1;
}
} while (fail);

/* On amd64 sometimes the bottom 32-bits of r == the bottom 32-bits of buffer
* but the top 32-bits of r have overflown to 0xffffffff (seriously, getcwd
* so we return the buffer here since it has a pointer to the valid string
*/
return buffer;
}
23 changes: 23 additions & 0 deletions src/mono/mono/eglib/gmisc-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <config.h>
#include <stdlib.h>
#include <errno.h>
#include <glib.h>
#include <pthread.h>

Expand Down Expand Up @@ -201,3 +202,25 @@ g_get_tmp_dir (void)
return tmp_dir;
}

gchar *
g_get_current_dir (void)
{
int s = 32;
char *buffer = NULL, *r;
gboolean fail;

do {
buffer = g_realloc (buffer, s);
r = getcwd (buffer, s);
fail = (r == NULL && errno == ERANGE);
if (fail) {
s <<= 1;
}
} while (fail);

/* On amd64 sometimes the bottom 32-bits of r == the bottom 32-bits of buffer
* but the top 32-bits of r have overflown to 0xffffffff (seriously, getcwd
* so we return the buffer here since it has a pointer to the valid string
*/
return buffer;
}
32 changes: 32 additions & 0 deletions src/mono/mono/eglib/gmisc-win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,35 @@ g_get_tmp_dir (void)
}
return tmp_dir;
}

gchar *
g_get_current_dir (void)
{
gunichar2 *buffer = NULL;
gchar* val = NULL;
gint32 retval, buffer_size = MAX_PATH;

buffer = g_new (gunichar2, buffer_size);
retval = GetCurrentDirectoryW (buffer_size, buffer);

if (retval != 0) {
// the size might be larger than MAX_PATH
// https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
if (retval > buffer_size) {
buffer_size = retval;
buffer = g_realloc (buffer, buffer_size*sizeof(gunichar2));
retval = GetCurrentDirectoryW (buffer_size, buffer);
}

val = u16to8 (buffer);
} else {
if (GetLastError () != ERROR_ENVVAR_NOT_FOUND) {
val = g_malloc (1);
*val = 0;
}
}

g_free (buffer);

return val;
}

0 comments on commit 6f68bbd

Please sign in to comment.