aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2007-10-13 11:06:43 +0000
committerCorinna Vinschen <corinna@vinschen.de>2007-10-13 11:06:43 +0000
commitfc7290fd39c59e1b4733520f40f8243ba5b40c95 (patch)
tree333ad0602fde44b9fd1b59e96d02c3db528d5bd8
parent8cca1e6c9375f0eeba9b0df27df67427971481ca (diff)
downloadnewlib-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/ChangeLog8
-rw-r--r--winsup/cygwin/ntdll.h1
-rw-r--r--winsup/cygwin/path.cc50
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);