win32: use ALLOCV

* win32/file.c (rb_readlink): use ALLOCV to get rid potential
  memory leak by NoMemoryError in ALLOCV.

* win32/win32.c (w32_readlink): allocate WCHAR path name and
  reparse buffer together.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51737 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-09-02 04:14:42 +00:00
parent 71f2c19a9c
commit 6bbd9104cb
2 changed files with 12 additions and 15 deletions

View File

@ -663,7 +663,7 @@ VALUE
rb_readlink(VALUE path) rb_readlink(VALUE path)
{ {
DWORD len; DWORD len;
VALUE wtmp = 0, str; VALUE wtmp = 0, wpathbuf, str;
rb_w32_reparse_buffer_t rbuf, *rp = &rbuf; rb_w32_reparse_buffer_t rbuf, *rp = &rbuf;
WCHAR *wpath, *wbuf; WCHAR *wpath, *wbuf;
rb_encoding *enc; rb_encoding *enc;
@ -677,16 +677,17 @@ rb_readlink(VALUE path)
path = fix_string_encoding(path, enc); path = fix_string_encoding(path, enc);
cp = CP_UTF8; cp = CP_UTF8;
} }
wpath = mbstr_to_wstr(cp, RSTRING_PTR(path), len = MultiByteToWideChar(cp, 0, RSTRING_PTR(path), RSTRING_LEN(path), NULL, 0);
RSTRING_LEN(path)+rb_enc_mbminlen(enc), NULL); wpath = ALLOCV_N(WCHAR, wpathbuf, len+1);
if (!wpath) rb_memerror(); MultiByteToWideChar(cp, 0, RSTRING_PTR(path), RSTRING_LEN(path), wpath, len);
wpath[len] = L'\0';
e = rb_w32_read_reparse_point(wpath, rp, sizeof(rbuf), &wbuf, &len); e = rb_w32_read_reparse_point(wpath, rp, sizeof(rbuf), &wbuf, &len);
if (e == ERROR_MORE_DATA) { if (e == ERROR_MORE_DATA) {
size_t size = rb_w32_reparse_buffer_size(len + 1); size_t size = rb_w32_reparse_buffer_size(len + 1);
rp = ALLOCV(wtmp, size); rp = ALLOCV(wtmp, size);
e = rb_w32_read_reparse_point(wpath, rp, size, &wbuf, &len); e = rb_w32_read_reparse_point(wpath, rp, size, &wbuf, &len);
} }
free(wpath); ALLOCV_END(wpathbuf);
if (e) { if (e) {
ALLOCV_END(wtmp); ALLOCV_END(wtmp);
rb_syserr_fail_path(rb_w32_map_errno(e), path); rb_syserr_fail_path(rb_w32_map_errno(e), path);

View File

@ -4813,27 +4813,23 @@ rb_w32_read_reparse_point(const WCHAR *path, rb_w32_reparse_buffer_t *rp,
static ssize_t static ssize_t
w32_readlink(UINT cp, const char *path, char *buf, size_t bufsize) w32_readlink(UINT cp, const char *path, char *buf, size_t bufsize)
{ {
WCHAR *wpath, *wname;
VALUE wtmp; VALUE wtmp;
size_t size = rb_w32_reparse_buffer_size(bufsize); DWORD len = MultiByteToWideChar(cp, 0, path, -1, NULL, 0);
rb_w32_reparse_buffer_t *rp = ALLOCV(wtmp, size); size_t size = rb_w32_reparse_buffer_size(len);
DWORD len; WCHAR *wname, *wpath = ALLOCV(wtmp, size + sizeof(WCHAR) * len);
rb_w32_reparse_buffer_t *rp = (void *)(wpath + len);
ssize_t ret; ssize_t ret;
int e; int e;
wpath = mbstr_to_wstr(cp, path, -1, NULL); MultiByteToWideChar(cp, 0, path, -1, wpath, len);
if (!wpath) {
ALLOCV_END(wtmp);
return -1;
}
e = rb_w32_read_reparse_point(wpath, rp, size, &wname, &len); e = rb_w32_read_reparse_point(wpath, rp, size, &wname, &len);
free(wpath);
if (e && e != ERROR_MORE_DATA) { if (e && e != ERROR_MORE_DATA) {
ALLOCV_END(wtmp); ALLOCV_END(wtmp);
errno = map_errno(e); errno = map_errno(e);
return -1; return -1;
} }
ret = WideCharToMultiByte(cp, 0, wname, len, buf, bufsize, NULL, NULL); ret = WideCharToMultiByte(cp, 0, wname, len, buf, bufsize, NULL, NULL);
ALLOCV_END(wtmp);
if (e) { if (e) {
ret = bufsize; ret = bufsize;
} }