diff options
| author | Greg Ercolano <erco@seriss.com> | 2014-01-13 14:41:23 +0000 |
|---|---|---|
| committer | Greg Ercolano <erco@seriss.com> | 2014-01-13 14:41:23 +0000 |
| commit | bffc6b36ae1dff9fb6e51399742fb4dc8e8f6539 (patch) | |
| tree | f7a9b1fc2074915abee4776068da5717b568c49b /src/Fl_Tree.cxx | |
| parent | 49e4b8e3fa966e4f0cd6d3527590bfc65e91f2ae (diff) | |
Fix small memleak in parse_path() if user tries to add() paths like "" or "/".
Also shrunk implementation code.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10054 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Tree.cxx')
| -rw-r--r-- | src/Fl_Tree.cxx | 52 |
1 files changed, 17 insertions, 35 deletions
diff --git a/src/Fl_Tree.cxx b/src/Fl_Tree.cxx index 53dcbe515..03e0a1364 100644 --- a/src/Fl_Tree.cxx +++ b/src/Fl_Tree.cxx @@ -33,50 +33,32 @@ static void scroll_cb(Fl_Widget*,void *data) { } // INTERNAL: Parse elements from 'path' into an array of null terminated strings -// Handles escape characters. -// Path="/aa/bb" -// Return: arr[0]="aa", arr[1]="bb", arr[2]=0 +// Handles escape characters, ignores multiple /'s. +// Path="/aa/bb", returns arr[0]="aa", arr[1]="bb", arr[2]=0. // Caller must call free_path(arr). // static char **parse_path(const char *path) { - while ( *path == '/' ) path++; // skip leading '/' - // First pass: identify, null terminate, and count separators - int seps = 1; // separator count (1: first item) - int arrsize = 1; // array size (1: first item) - char *save = strdup(path); // make copy we can modify - char *sin = save, *sout = save; - while ( *sin ) { - if ( *sin == '\\' ) { // handle escape character - *sout++ = *++sin; - if ( *sin ) ++sin; - } else if ( *sin == '/' ) { // handle submenu - *sout++ = 0; - sin++; - seps++; - arrsize++; - } else { // all other chars - *sout++ = *sin++; - } - } - *sout = 0; - arrsize++; // (room for terminating NULL) - // Second pass: create array, save nonblank elements - char **arr = (char**)malloc(sizeof(char*) * arrsize); - int t = 0; - sin = save; - while ( seps-- > 0 ) { - if ( *sin ) { arr[t++] = sin; } // skips empty fields, e.g. '//' - sin += (strlen(sin) + 1); + int len = strlen(path); + char *cp = new char[(len+1)], *word = cp, *s = cp; // freed below or in free_path() + char **ap = new char*[(len+1)], **arr = ap; // overallocates arr[] + while (1) { + if (*path =='/' || *path == 0) { // handle path sep or eos + if (word != s) { *s++ = 0; *arr++= word; word = s; } + if ( !*path++) break; else continue; // eos? done, else cont + } else if ( *path == '\\' ) { // handle escape + if ( *(++path) ) { *s++ = *path++; } else continue; + } else { *s++ = *path++; } // handle normal char } - arr[t] = 0; - return(arr); + *arr = 0; + if ( arr == ap ) delete[] cp; // empty arr[]? delete since free_path() can't + return ap; } // INTERNAL: Free an array 'arr' returned by parse_path() static void free_path(char **arr) { if ( arr ) { - if ( arr[0] ) { free((void*)arr[0]); } - free((void*)arr); + if ( arr[0] ) { delete[] arr[0]; } // deletes cp in parse_path + delete[] arr; // deletes ptr array } } |
