diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-10-13 11:06:43 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-10-13 11:06:43 +0000 |
commit | fc7290fd39c59e1b4733520f40f8243ba5b40c95 (patch) | |
tree | 333ad0602fde44b9fd1b59e96d02c3db528d5bd8 | |
parent | 8cca1e6c9375f0eeba9b0df27df67427971481ca (diff) | |
download | newlib-fc7290fd39c59e1b4733520f40f8243ba5b40c95.zip newlib-fc7290fd39c59e1b4733520f40f8243ba5b40c95.tar.gz newlib-fc7290fd39c59e1b4733520f40f8243ba5b40c95.tar.bz2 |
* ntdll.h (STATUS_END_OF_FILE): Define.
* path.cc (symlink_info::check_shortcut): Use NT function to get file
size. Reintroduce checking file size before reading it. Eliminiate
close_it label.
(symlink_info::check_sysfile): Check for EOF condition.
-rw-r--r-- | winsup/cygwin/ChangeLog | 8 | ||||
-rw-r--r-- | winsup/cygwin/ntdll.h | 1 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 50 |
3 files changed, 41 insertions, 18 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3a2e9c2..aed46e6 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2007-10-12 Corinna Vinschen <corinna@vinschen.de> + + * ntdll.h (STATUS_END_OF_FILE): Define. + * path.cc (symlink_info::check_shortcut): Use NT function to get file + size. Reintroduce checking file size before reading it. Eliminiate + close_it label. + (symlink_info::check_sysfile): Check for EOF condition. + 2007-10-11 Corinna Vinschen <corinna@vinschen.de> * path.cc (basename): Return pointer into the path argument itself. diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 1363341..57bbfbb 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -17,6 +17,7 @@ #define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d) #define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xc000000f) #define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xc0000010) +#define STATUS_END_OF_FILE ((NTSTATUS) 0xc0000011) #define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013) #define STATUS_ACCESS_DENIED ((NTSTATUS) 0xc0000022) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023) diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index aacf057..108ac67 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -3158,19 +3158,30 @@ symlink_info::check_shortcut (HANDLE h) char *buf, *cp; unsigned short len; int res = 0; - DWORD size; + NTSTATUS status; IO_STATUS_BLOCK io; + FILE_STANDARD_INFORMATION fsi; - size = GetFileSize (h, NULL); - buf = (char *) alloca (size + 1); + status = NtQueryInformationFile (h, &io, &fsi, sizeof fsi, + FileStandardInformation); + if (!NT_SUCCESS (status)) + { + set_error (EIO); + return 0; + } + if (fsi.EndOfFile.QuadPart <= sizeof (win_shortcut_hdr) + || fsi.EndOfFile.QuadPart > 4 * 65536) + return 0; + buf = (char *) alloca (fsi.EndOfFile.LowPart + 1); if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL, - &io, buf, size, NULL, NULL))) + &io, buf, fsi.EndOfFile.LowPart, NULL, NULL))) { set_error (EIO); - goto close_it; + return 0; } file_header = (win_shortcut_hdr *) buf; - if (io.Information != size || !cmp_shortcut_header (file_header)) + if (io.Information != fsi.EndOfFile.LowPart + || !cmp_shortcut_header (file_header)) goto file_not_symlink; cp = buf + sizeof (win_shortcut_hdr); if (file_header->flags & WSH_FLAG_IDLIST) /* Skip ITEMIDLIST */ @@ -3185,7 +3196,7 @@ symlink_info::check_shortcut (HANDLE h) { /* Has appended full path? If so, use it instead of description. */ unsigned short relpath_len = *(unsigned short *) (cp + len); - if (cp + len + 2 + relpath_len < buf + size) + if (cp + len + 2 + relpath_len < buf + fsi.EndOfFile.LowPart) { cp += len + 2 + relpath_len; len = *(unsigned short *) cp; @@ -3198,15 +3209,13 @@ symlink_info::check_shortcut (HANDLE h) } if (res) /* It's a symlink. */ pflags = PATH_SYMLINK | PATH_LNK; - goto close_it; + return res; file_not_symlink: /* Not a symlink, see if executable. */ if (!(pflags & PATH_ALL_EXEC) && has_exec_chars ((const char *) &file_header, io.Information)) pflags |= PATH_EXEC; - -close_it: - return res; + return 0; } int @@ -3214,14 +3223,17 @@ symlink_info::check_sysfile (HANDLE h) { char cookie_buf[sizeof (SYMLINK_COOKIE) - 1]; char srcbuf[SYMLINK_MAX + 2]; + NTSTATUS status; IO_STATUS_BLOCK io; int res = 0; - if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL, &io, - cookie_buf, sizeof (cookie_buf), NULL, NULL))) + status = NtReadFile (h, NULL, NULL, NULL, &io, cookie_buf, + sizeof (cookie_buf), NULL, NULL); + if (!NT_SUCCESS (status)) { debug_printf ("ReadFile1 failed"); - set_error (EIO); + if (status != STATUS_END_OF_FILE) + set_error (EIO); } else if (io.Information == sizeof (cookie_buf) && memcmp (cookie_buf, SYMLINK_COOKIE, sizeof (cookie_buf)) == 0) @@ -3229,16 +3241,18 @@ symlink_info::check_sysfile (HANDLE h) /* It's a symlink. */ pflags = PATH_SYMLINK; - if (!NT_SUCCESS (NtReadFile (h, NULL, NULL, NULL, &io, - srcbuf, SYMLINK_MAX + 2, NULL, NULL))) + status = NtReadFile (h, NULL, NULL, NULL, &io, srcbuf, + SYMLINK_MAX + 2, NULL, NULL); + if (!NT_SUCCESS (status)) { debug_printf ("ReadFile2 failed"); - set_error (EIO); + if (status != STATUS_END_OF_FILE) + set_error (EIO); } else if (io.Information > SYMLINK_MAX + 1) { debug_printf ("symlink string too long"); - set_error (EIO); + } else res = posixify (srcbuf); |