ruby-changes:39559
From: nobu <ko1@a...>
Date: Wed, 19 Aug 2015 23:48:27 +0900 (JST)
Subject: [ruby-changes:39559] nobu:r51640 (trunk): win32.c: support known reparse points only
nobu 2015-08-19 23:48:09 +0900 (Wed, 19 Aug 2015) New Revision: 51640 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51640 Log: win32.c: support known reparse points only * win32/win32.c (winnt_lstat): check reparse point tags and treat supported tags only as symbolic links. [ruby-core:70454] [Bug #11462] Modified files: trunk/ChangeLog trunk/win32/win32.c Index: ChangeLog =================================================================== --- ChangeLog (revision 51639) +++ ChangeLog (revision 51640) @@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Aug 19 23:48:06 2015 Nobuyoshi Nakada <nobu@r...> + + * win32/win32.c (winnt_lstat): check reparse point tags and treat + supported tags only as symbolic links. + [ruby-core:70454] [Bug #11462] + Tue Aug 18 20:05:49 2015 NARUSE, Yui <naruse@r...> * thread_pthread.c (reserve_stack): ensure the memory is really Index: win32/win32.c =================================================================== --- win32/win32.c (revision 51639) +++ win32/win32.c (revision 51640) @@ -4656,31 +4656,33 @@ link(const char *from, const char *to) https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4656 #endif /* License: Ruby's */ -ssize_t -rb_w32_wreadlink(const WCHAR *path, WCHAR *buf, size_t bufsize) +typedef struct { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[MAXPATHLEN * 2]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[MAXPATHLEN * 2]; + } MountPointReparseBuffer; + }; +} reparse_buffer_t; + +/* License: Ruby's */ +static int +reparse_symlink(const WCHAR *path, reparse_buffer_t *rp) { - struct { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[MAXPATHLEN * 2]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[MAXPATHLEN * 2]; - } MountPointReparseBuffer; - }; - } rp; HANDLE f; DWORD ret; int e = 0; @@ -4695,8 +4697,7 @@ rb_w32_wreadlink(const WCHAR *path, WCHA https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4697 get_proc_address("kernel32", "DeviceIoControl", NULL); } if (!device_io_control) { - errno = ENOSYS; - return -1; + return ENOSYS; } f = CreateFileW(path, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, @@ -4704,19 +4705,29 @@ rb_w32_wreadlink(const WCHAR *path, WCHA https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4705 FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (f == INVALID_HANDLE_VALUE) { - errno = map_errno(GetLastError()); - return -1; + return map_errno(GetLastError()); } if (!device_io_control(f, FSCTL_GET_REPARSE_POINT, NULL, 0, - &rp, sizeof(rp), &ret, NULL)) { + rp, sizeof(*rp), &ret, NULL)) { e = map_errno(GetLastError()); } - else if (rp.ReparseTag != IO_REPARSE_TAG_SYMLINK && - rp.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT){ + else if (rp->ReparseTag != IO_REPARSE_TAG_SYMLINK && + rp->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT){ e = EINVAL; } - else { + CloseHandle(f); + return e; +} + +ssize_t +rb_w32_wreadlink(const WCHAR *path, WCHAR *buf, size_t bufsize) +{ + reparse_buffer_t rp; + int e = reparse_symlink(path, &rp); + DWORD ret; + + if (!e) { void *name; if (rp.ReparseTag == IO_REPARSE_TAG_SYMLINK) { name = ((char *)rp.SymbolicLinkReparseBuffer.PathBuffer + @@ -4736,9 +4747,7 @@ rb_w32_wreadlink(const WCHAR *path, WCHA https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L4747 bufsize *= sizeof(WCHAR); memcpy(buf, name, ret > bufsize ? bufsize : ret); } - - CloseHandle(f); - if (e) { + else { errno = e; return -1; } @@ -5279,11 +5288,15 @@ winnt_lstat(const WCHAR *path, struct st https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L5288 return -1; } if (GetFileAttributesExW(path, GetFileExInfoStandard, (void*)&wfa)) { + reparse_buffer_t rp; if (wfa.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { /* TODO: size in which encoding? */ - st->st_size = 0; + if (reparse_symlink(path, &rp) == 0) + st->st_size = 0; + else + wfa.dwFileAttributes &= ~FILE_ATTRIBUTE_REPARSE_POINT; } - else if (wfa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (wfa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (check_valid_dir(path)) return -1; st->st_size = 0; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/