[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]