diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2013-04-03 11:20:36 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2013-04-03 11:20:36 +0000 |
commit | d1bef83800afb91ab73701b64a1e770662a5bbdd (patch) | |
tree | df2aec2a9dbb9bc49e98176be128036a96145562 /winsup/cygwin/path.cc | |
parent | 2e463c77deb8176fe3c160614767b477d605cce4 (diff) | |
download | cygnal-d1bef83800afb91ab73701b64a1e770662a5bbdd.tar.gz cygnal-d1bef83800afb91ab73701b64a1e770662a5bbdd.tar.bz2 cygnal-d1bef83800afb91ab73701b64a1e770662a5bbdd.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r-- | winsup/cygwin/path.cc | 36 |
1 files changed, 29 insertions, 7 deletions
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; |