waneck/systools

openFile: when multi is false, the path returned end with extra "/" (Win)

guoboism opened this issue · 2 comments

Hi,

There is a bug about the newly committed "multi" option to the OpenFileDialog. On windows(of course), when multi is false, openFile will return a string ending with extra "/", like "C:/folder/file.txt/".

I checked the code and did experiments and notice 2 things:

1 systools_dialogs_open_file() in project/src/win/dialogs.c rely on the value of extra char after normal ending \0

if (GetOpenFileName(&ofn)) {        
        char* file = ofn.lpstrFile;
        char* folder = NULL;
        long pass = 1;
        while(*file!=0) {
            size_t len = strlen(file);          
            len++;
            if (pass==1) {
                r->strings = realloc(r->strings,sizeof(char*)*(r->count+1));
                r->strings[r->count] = strdup(file);
                folder = file;          
                r->count++;
            } else if (pass==2) {
                r->strings[0] = realloc(r->strings[0],strlen(r->strings[0])+strlen(file)+2);
                strcat(r->strings[0], "\\");
                strcat(r->strings[0], file);                                
            } else {
                r->strings = realloc(r->strings,sizeof(char*)*(r->count+1));
                r->strings[r->count] = malloc(strlen(folder)+strlen(file)+2);
                strcpy(r->strings[r->count], folder);
                strcat(r->strings[r->count], "\\");
                strcat(r->strings[r->count], file);
                r->count++;
            }
            file += len;
            pass++;     
        }       
    }   

On second loop, file would be ofn.lpstrFile + strlen(ofn.lpstrFile)+1

2 Windows return different things by GetOpenFileName(): (0 stands for \0; * for random value)

With OFN_ALLOWMULTISELECT, when selecting 2 or more files, lpstrFile would be: path0fileA0fileB00

With OFN_ALLOWMULTISELECT, when selecting 1 file, lpstrFile would be pathfileA00

(Windows somehow make sure there are two \0 at the end and code works well)

Without OFN_ALLOWMULTISELECT, lpstrFile would be pathfileA0*, and it will go into pass2, and have extra "/" added

Solution: memset 0 for malloc-ed ofn.lpstrFile (Line 98)

ofn.lpstrFile = malloc(8192);
memset(ofn.lpstrFile, 0 , 8192);

Can you submit a PR?

here we go