From d1bef83800afb91ab73701b64a1e770662a5bbdd Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 3 Apr 2013 11:20:36 +0000 Subject: * 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. --- winsup/cygwin/ChangeLog | 11 +++++++++++ winsup/cygwin/path.cc | 36 +++++++++++++++++++++++++++++------- 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 + + * 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 * 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; -- cgit v1.2.3