summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2017-07-07 16:19:26 +0000
committerMatthias Melcher <fltk@matthiasm.com>2017-07-07 16:19:26 +0000
commit1a7dc778513a5d4a124a232ad556608c0ad3f8f5 (patch)
tree7811b1b484667f09ee0821d0ee8901c238e76517
parent9f69df923fa4a672274c013f8969416f19925be8 (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.cxx43
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;
}