Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-04-03 15:20:36 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-04-03 15:20:36 +0400
commitd1bef83800afb91ab73701b64a1e770662a5bbdd (patch)
treedf2aec2a9dbb9bc49e98176be128036a96145562
parent2e463c77deb8176fe3c160614767b477d605cce4 (diff)
* path.cc (class suffix_scan): Add member namelen.
(suffix_scan::name_len): New method. (suffix_scan::has): Store namelen since we have it already anyway. Add a bit of explanation and a FIXME to comment. (suffix_scan::next): Never attach extra .lnk suffix if resulting filename length exceeds NAME_LEN. (symlink_info::check): Bail out immediately with ENAMETOOLONG if filename length exceeds NAME_LEN.
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/path.cc36
2 files changed, 40 insertions, 7 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 4b04b3334..e2cf0dbab 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+2013-04-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * path.cc (class suffix_scan): Add member namelen.
+ (suffix_scan::name_len): New method.
+ (suffix_scan::has): Store namelen since we have it already anyway.
+ Add a bit of explanation and a FIXME to comment.
+ (suffix_scan::next): Never attach extra .lnk suffix if resulting
+ filename length exceeds NAME_LEN.
+ (symlink_info::check): Bail out immediately with ENAMETOOLONG if
+ filename length exceeds NAME_LEN.
+
2013-03-31 Christopher Faylor <me.cygwin2013@cgf.cx>
* child_info.h (cygheap_exec_info::sigmask): Declare new field.
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 1057314fe..4d3161922 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2147,11 +2147,13 @@ class suffix_scan
const suffix_info *suffixes, *suffixes_start;
int nextstate;
char *eopath;
+ size_t namelen;
public:
const char *path;
char *has (const char *, const suffix_info *);
int next ();
int lnk_match () {return nextstate >= SCAN_APPENDLNK;}
+ size_t name_len () {return namelen;}
};
char *
@@ -2192,8 +2194,15 @@ suffix_scan::has (const char *in_path, const suffix_info *in_suffixes)
ext_here = eopath;
done:
- /* Avoid attaching suffixes if the resulting filename would be invalid. */
- if (eopath - fname > NAME_MAX - 4)
+ namelen = eopath - fname;
+ /* Avoid attaching suffixes if the resulting filename would be invalid.
+ For performance reasons we don't check the length of a suffix, since
+ we know that all suffixes are 4 chars in length.
+
+ FIXME: This is not really correct. A fully functional test should
+ work on wide character paths. This would probably also speed
+ up symlink_info::check. */
+ if (namelen > NAME_MAX - 4)
{
nextstate = SCAN_JUSTCHECKTHIS;
suffixes = NULL;
@@ -2234,8 +2243,13 @@ suffix_scan::next ()
return 1;
case SCAN_LNK:
case SCAN_APPENDLNK:
- strcat (eopath, ".lnk");
nextstate = SCAN_DONE;
+ if (namelen + (*eopath ? 8 : 4) > NAME_MAX)
+ {
+ *eopath = '\0';
+ return 0;
+ }
+ strcat (eopath, ".lnk");
return 1;
default:
*eopath = '\0';
@@ -2243,7 +2257,8 @@ suffix_scan::next ()
}
while (suffixes && suffixes->name)
- if (nextstate == SCAN_EXTRALNK && !suffixes->addon)
+ if (nextstate == SCAN_EXTRALNK
+ && (!suffixes->addon || namelen > NAME_MAX - 8))
suffixes++;
else
{
@@ -2362,13 +2377,20 @@ restart:
mode = 0;
pflags &= ~(PATH_SYMLINK | PATH_LNK | PATH_REP);
- ext_here = suffix.has (path, suffixes);
- extn = ext_here - path;
-
PVOID eabuf = &nfs_aol_ffei;
ULONG easize = sizeof nfs_aol_ffei;
+ ext_here = suffix.has (path, suffixes);
+ extn = ext_here - path;
bool had_ext = !!*ext_here;
+
+ /* If the filename is too long, don't even try. */
+ if (suffix.name_len () > NAME_MAX)
+ {
+ set_error (ENAMETOOLONG);
+ goto file_not_symlink;
+ }
+
while (suffix.next ())
{
error = 0;