diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2017-07-07 16:19:26 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2017-07-07 16:19:26 +0000 |
| commit | 1a7dc778513a5d4a124a232ad556608c0ad3f8f5 (patch) | |
| tree | 7811b1b484667f09ee0821d0ee8901c238e76517 | |
| parent | 9f69df923fa4a672274c013f8969416f19925be8 (diff) | |
STR #2034: Fl_Preferences::getUserdataPath() is much more careful when creating a pathname based on the preferences filename. Among other things, remove a possible buffer overflow.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12299 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | src/Fl_Preferences.cxx | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx index 8ee9ab190..066ac06e4 100644 --- a/src/Fl_Preferences.cxx +++ b/src/Fl_Preferences.cxx @@ -935,22 +935,53 @@ int Fl_Preferences::RootNode::write() { } // get the path to the preferences directory +// - copy the path into the buffer at "path" +// - if the resulting path is longer than "pathlen", it will be cropped char Fl_Preferences::RootNode::getPath( char *path, int pathlen ) { if (!filename_) // RUNTIME preferences return 1; // return 1 (not -1) to be consistent with fl_make_path() + + if (pathlen<=0) + return 1; + + // copy the root filepath into the provided buffer strlcpy( path, filename_, pathlen); - char *s; - for ( s = path; *s; s++ ) if ( *s == '\\' ) *s = '/'; - s = strrchr( path, '.' ); - if ( !s ) return 0; - *s = 0; + char *name = 0L, *ext = 0L; + + // use Unix style separators + { char *s; for ( s = path; *s; s++ ) if ( *s == '\\' ) *s = '/'; } + + // find the start of the filename inside the path + name = strrchr( path, '/' ); + // this is a safety measure. The root path should be absolute and contain '/'s + if (name) + name++; // point right after the '/' character + else + name = path; // point at the first character of a filename-only path + + // find the last '.' which may be the start of a file extension + ext = strrchr( path, '.' ); + + if ( (ext==0L) || (ext<name) ) { + if (strlen(name)==0) { + // emty filenames will create a path with "prefs/" as a driectory name + strlcat( path, "prefs", pathlen ); + } else { + // filenames without extension will create a path with a ".data" extension + strlcat( path, ".data", pathlen ); + } + } else { + // filenames with an existing extension will create a path without it + *ext = 0; // end the string right here + } + char ret = fl_make_path( path ); // unix: make sure that system prefs dir. is user-readable if (Fl::system_driver()->preferences_need_protection_check() && strncmp(path, "/etc/fltk/", 10) == 0) { fl_chmod(path, 0755); // rwxr-xr-x } - strcpy( s, "/" ); + strlcat( path, "/", pathlen ); return ret; } |
