Skip to content

Commit 6f68bbd

Browse files
authored
[mono] win32 implementation of g_get_current_dir (dotnet#58523)
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.
1 parent f41b259 commit 6f68bbd

File tree

3 files changed

+55
-23
lines changed

3 files changed

+55
-23
lines changed

src/mono/mono/eglib/gfile-posix.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -161,26 +161,3 @@ g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **gerror)
161161
}
162162
return fd;
163163
}
164-
165-
gchar *
166-
g_get_current_dir (void)
167-
{
168-
int s = 32;
169-
char *buffer = NULL, *r;
170-
gboolean fail;
171-
172-
do {
173-
buffer = g_realloc (buffer, s);
174-
r = getcwd (buffer, s);
175-
fail = (r == NULL && errno == ERANGE);
176-
if (fail) {
177-
s <<= 1;
178-
}
179-
} while (fail);
180-
181-
/* On amd64 sometimes the bottom 32-bits of r == the bottom 32-bits of buffer
182-
* but the top 32-bits of r have overflown to 0xffffffff (seriously, getcwd
183-
* so we return the buffer here since it has a pointer to the valid string
184-
*/
185-
return buffer;
186-
}

src/mono/mono/eglib/gmisc-unix.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include <config.h>
3030
#include <stdlib.h>
31+
#include <errno.h>
3132
#include <glib.h>
3233
#include <pthread.h>
3334

@@ -201,3 +202,25 @@ g_get_tmp_dir (void)
201202
return tmp_dir;
202203
}
203204

205+
gchar *
206+
g_get_current_dir (void)
207+
{
208+
int s = 32;
209+
char *buffer = NULL, *r;
210+
gboolean fail;
211+
212+
do {
213+
buffer = g_realloc (buffer, s);
214+
r = getcwd (buffer, s);
215+
fail = (r == NULL && errno == ERANGE);
216+
if (fail) {
217+
s <<= 1;
218+
}
219+
} while (fail);
220+
221+
/* On amd64 sometimes the bottom 32-bits of r == the bottom 32-bits of buffer
222+
* but the top 32-bits of r have overflown to 0xffffffff (seriously, getcwd
223+
* so we return the buffer here since it has a pointer to the valid string
224+
*/
225+
return buffer;
226+
}

src/mono/mono/eglib/gmisc-win32.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,35 @@ g_get_tmp_dir (void)
232232
}
233233
return tmp_dir;
234234
}
235+
236+
gchar *
237+
g_get_current_dir (void)
238+
{
239+
gunichar2 *buffer = NULL;
240+
gchar* val = NULL;
241+
gint32 retval, buffer_size = MAX_PATH;
242+
243+
buffer = g_new (gunichar2, buffer_size);
244+
retval = GetCurrentDirectoryW (buffer_size, buffer);
245+
246+
if (retval != 0) {
247+
// the size might be larger than MAX_PATH
248+
// https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd
249+
if (retval > buffer_size) {
250+
buffer_size = retval;
251+
buffer = g_realloc (buffer, buffer_size*sizeof(gunichar2));
252+
retval = GetCurrentDirectoryW (buffer_size, buffer);
253+
}
254+
255+
val = u16to8 (buffer);
256+
} else {
257+
if (GetLastError () != ERROR_ENVVAR_NOT_FOUND) {
258+
val = g_malloc (1);
259+
*val = 0;
260+
}
261+
}
262+
263+
g_free (buffer);
264+
265+
return val;
266+
}

0 commit comments

Comments
 (0)