fat_io_lib icon indicating copy to clipboard operation
fat_io_lib copied to clipboard

Files with an extension of 1 or 2 characters do not open (use with esp8266)

Open slacky1965 opened this issue 3 years ago • 3 comments

`void ICACHE_FLASH_ATTR list_html() { FL_DIR dir; struct fs_dir_ent de; char *err = NULL; char buff[512]; char spaces[16]; FILE *fp; size_t len, total_len; char *folder = "/html";

if (fl_opendir(folder, &dir)) {
    os_sprintf(buff, "Directory: %s\n\n", folder);
    os_printf(buff);

    total_len = 0;

    while (fl_readdir(&dir, &de) == 0) {
        if (!de.is_dir) {
            os_sprintf(buff, "%ld", de.size);
            len = 7 - strlen(buff);
            memset(spaces, ' ', len);
            spaces[len] = 0;
            os_sprintf(buff, "  %s%ld    %s\n", spaces, de.size, de.filename);
            total_len += de.size;
            os_printf(buff);
            os_sprintf(buff, "%s%s%s", folder, "/", de.filename);
            fp = fopen(buff, "rb");
            if (fp == NULL) {
                err = "Cannot open file";
                os_printf("%s \"%s\". (%s:%u)\n", err, de.filename, __FILE__, __LINE__);
            } else {
                fclose(fp);
            }
        }
    }
    fl_closedir(&dir);
    os_printf("\nUsed %d\tbytes\n", total_len);
}

} `

log

`Directory: /html

 5866    config.html
 6429    favicon.ico
 1320    index.html
  758    log.html
  453    ok.html
 2840    scripts.js

Cannot open file "scripts.js". (user_main.c:106) 453 settings.html 2053 style.css 1588 upload.html 266 license 948 main.c Cannot open file "main.c". (user_main.c:106) 948 main.cc Cannot open file "main.cc". (user_main.c:106) 948 main.ccc

Used 24870 bytes`

slacky1965 avatar Feb 28 '22 19:02 slacky1965

sorry, the formatting leaves much to be desired

slacky1965 avatar Feb 28 '22 19:02 slacky1965

This project is used by Ventoy github project and I found same issue. File 7za.exe would open OK but 7za.xz failed to open. I fixed it by adding a space to the filename extension when calling fopen - "7za.xz "

The fat_io_lib code always seems to assume that there are always either zero or three characters in the extension?

steve6375 avatar Sep 10 '22 21:09 steve6375

in fat_string.c fatfs_compare_names

        // Verify that the file extension lengths match!
        if (strlen(ext1) != strlen(ext2))
            return 0;

        // If they dont match
        if (FileString_StrCmpNoCase(ext1, ext2, (int)strlen(ext1))!=0)
            return 0;

ext1 could contain xz[/0] and ext2 could contain xz[space] so will fail.

for filename test you use

    // Find length without trailing spaces (before ext)
    file1Len = FileString_TrimLength(strA, file1Len);
    file2Len = FileString_TrimLength(strB, file2Len);

but you do not use FileString_TrimLength for extension test.

I am not very good with C - but here is revised code which seems to work with files with 1, 2 or 3 character file extensions. But you should check it!

Changed file: fat_string.zip

//-----------------------------------------------------------------------------
// fatfs_compare_names: Compare two filenames (without copying or changing originals)
// Returns 1 if match, 0 if not
//-----------------------------------------------------------------------------
int fatfs_compare_names(char* strA, char* strB)
{
    char *ext1 = NULL;
    char *ext2 = NULL;
    int ext1Pos, ext2Pos;
    int ext1Len, ext2Len;
    int file1Len, file2Len;

    // Get both files extension
    ext1Pos = FileString_GetExtension(strA);
    ext2Pos = FileString_GetExtension(strB);

    // NOTE: Extension position can be different for matching
    // filename if trailing space are present before it!
    // Check that if one has an extension, so does the other
    if ((ext1Pos==-1) && (ext2Pos!=-1))
        return 0;
    if ((ext2Pos==-1) && (ext1Pos!=-1))
        return 0;

    // If they both have extensions, compare them
    if (ext1Pos!=-1)
    {
        // Set pointer to start of extension
        ext1 = strA+ext1Pos+1;
        ext2 = strB+ext2Pos+1;

        // Verify that the file extension lengths match!
	ext1Len = strlen(ext1);
        ext2Len = strlen(ext2);
        ext1Len = FileString_TrimLength(ext1, ext1Len);
        ext2Len = FileString_TrimLength(ext2, ext2Len);
        if (ext1Len != ext2Len)
            return 0;

        // If they dont match
        if (FileString_StrCmpNoCase(ext1, ext2, ext1Len)!=0)
            return 0;

        // Filelength is upto extensions
        file1Len = ext1Pos;
        file2Len = ext2Pos;
    }
    // No extensions
    else
    {
        // Filelength is actual filelength
        file1Len = (int)strlen(strA);
        file2Len = (int)strlen(strB);
    }

    // Find length without trailing spaces (before ext)
    file1Len = FileString_TrimLength(strA, file1Len);
    file2Len = FileString_TrimLength(strB, file2Len);

    // Check the file lengths match
    if (file1Len!=file2Len)
        return 0;

    // Compare main part of filenames
    if (FileString_StrCmpNoCase(strA, strB, file1Len)!=0)
        return 0;
    else
        return 1;
}

steve6375 avatar Sep 11 '22 12:09 steve6375