Skip to content

Preloaded file case insensitive name collision throws uncaught exception #26327

@AlexWalsh2

Description

@AlexWalsh2

I found a related issue while working on #15245

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 5.0.2-git (83e1f4c)
clang version 23.0.0git (https://github.com/emscripten-core/llvm-project.git 7d5622f7917815d224b780309432ffe4729e4852)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin

Failing command line in full:

 ./emcc -g test/hello_world_file.cpp -o hello.html --preload-file test/hello_world_file.txt -s CASE_INSENSITIVE_FS=1 --preload-file test/hELlo_wORLd_fILe.tXt 

This compiles (hELlo_wORLd_fILe.tXt contents do not matter much, a slight variation of hello_world_file.txt was used) but, when run with

./emrun hello.html

The result is a page that hangs on a spinning logo and 'all downloads complete'. The console reports the following error:

Uncaught (in promise) ErrnoError: 
    ErrnoError http://localhost:6931/hello.js:2089
    mknod http://localhost:6931/hello.js:2650
    create http://localhost:6931/hello.js:2691
    createDataFile http://localhost:6931/hello.js:3464
    FS_createDataFile http://localhost:6931/hello.js:2015
    processPackageData http://localhost:6931/hello.js:179
    runWithFS http://localhost:6931/hello.js:192
hello.js:2089:11
still waiting on run dependencies: hello.js:976:18
    runDependencyWatcher http://localhost:6931/hello.js:976
dependency: fp /test/hello_world_file.txt hello.js:978:16
    runDependencyWatcher http://localhost:6931/hello.js:978
dependency: datafile_hello.data hello.js:978:16
    runDependencyWatcher http://localhost:6931/hello.js:978
(end of list) hello.js:981:16
    runDependencyWatcher http://localhost:6931/hello.js:981

Diagnosis

It seems that the bug occurs after the first file (hELlo_wORLd_fILe.tXt) is loaded. When loading the second file, the function mayCreate (libfs.js:395-405) will be called:

    mayCreate(dir, name) { // checking for /test/hello_world_file.txt
      if (!FS.isDir(dir.mode)) {
        return {{{ cDefs.ENOTDIR }}};
      }
      try {
        var node = FS.lookupNode(dir, name); // this respects CASE_INSENSITIVE_FS; hELlo_wORLd_fILe.tXt is the same as hello_world_file.txt

        return {{{ cDefs.EEXIST }}}; //thus, this is returned (20 in the compiled code)
      } catch (e) {
      }
      return FS.nodePermissions(dir, 'wx');
    }

This is then passed up to mknod (libfs.js:700-703), which throws the error

      var errCode = FS.mayCreate(parent, name); //this returns cDefs.EEXIST, aka 20
      if (errCode) {
        throw new FS.ErrnoError(errCode); //and thrown
      }

Proposed Solutions

It should be relatively simple to add a check for cDefs.EEXISTS inside a #if CASE_INSENSITIVE_FS block. There are several possibilities:

  1. Overwrite the Old File - Remove the old node (after other checks), then replace it. This seems to be in line with desired behavior in Files uploading into Virtual File System with -s CASE_INSENSITIVE_FS=1 #15245, so may solve both bugs at once.
  2. Keep Both - This would mean the namespace collision gets handled like a hash collision. Results are almost the same as Overwrite the Old File, except this uses more memory (which Files uploading into Virtual File System with -s CASE_INSENSITIVE_FS=1 #15245 wished to avoid).
  3. Skip the New File - A catch could be put somewhere along the path (createDataFile), which either swallows that error or does something to notify the user. When two files of the exact same (case sensitive) name are uploaded, this is what seems to happen (one is silently dropped)

I'd be happy to provide a PR with a fix for this.

Full link command and output with -v appended:

./emcc -g test/hello_world_file.cpp -o hello.html --preload-file test/hello_world_file.txt -s CASE_INSENSITIVE_FS=1 --preload-file test/hELlo_wORLd_fILe.tXt -v

/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin/clang -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot -DEMSCRIPTEN -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -g -v -c test/hello_world_file.cpp -o /tmp/emscripten_temp_0tijcxf2/hello_world_file.o
clang version 23.0.0git (https://github.com/emscripten-core/llvm-project.git 7d5622f7917815d224b780309432ffe4729e4852)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin
(in-process)
"/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin/clang-23" -cc1 -triple wasm32-unknown-emscripten -emit-obj -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello_world_file.cpp -mrelocation-model static -mframe-pointer=none -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -fvisibility=hidden -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -fdebug-compilation-dir=/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten -v -fcoverage-compilation-dir=/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten -resource-dir /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/lib/clang/23 -D EMSCRIPTEN -isysroot /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot -internal-isystem /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1 -internal-isystem /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/c++/v1 -internal-isystem /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/lib/clang/23/include -internal-isystem /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/wasm32-emscripten -internal-isystem /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include -fdeprecated-macro -ferror-limit 19 -fmessage-length=157 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fignore-exceptions -fexceptions -fcolor-diagnostics -iwithsysroot/include/fakesdl -iwithsysroot/include/compat -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -o /tmp/emscripten_temp_0tijcxf2/hello_world_file.o -x c++ test/hello_world_file.cpp
clang -cc1 version 23.0.0git based upon LLVM 23.0.0git default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/wasm32-emscripten/c++/v1"
ignoring nonexistent directory "/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/wasm32-emscripten"
#include "..." search starts here:
#include <...> search starts here:
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/fakesdl
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/compat
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include/c++/v1
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/lib/clang/23/include
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/include
End of search list.
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin/clang --version
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/tools/file_packager hello.data --from-emcc --preload test/hello_world_file.txt test/hELlo_wORLd_fILe.tXt
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin/wasm-ld -o hello.wasm /tmp/tmpewl8knd4libemscripten_js_symbols.so --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=_emscripten_stack_alloc --export=__wasm_call_ctors --export=_emscripten_stack_restore --export=strerror --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --no-growable-memory --initial-heap=16777216 --no-entry --stack-first --table-base=1 /tmp/emscripten_temp_0tijcxf2/hello_world_file.o -L/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/cache/sysroot/lib/wasm32-emscripten -L/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/src/lib -lGL-getprocaddr -lal -lhtml5 -lstubs-debug -lnoexit -lc-debug -ldlmalloc-debug -lcompiler_rt -lc++-debug-noexcept -lc++abi-debug-noexcept -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr
/mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/llvm-project/build/bin/llvm-objcopy hello.wasm hello.wasm '--remove-section=llvm.func_attr.annotate.*' --remove-section=producers
/home/linuxbrew/.linuxbrew/bin/node /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/tools/compiler.mjs -
/home/linuxbrew/.linuxbrew/bin/node /mnt/bigSSD/Master/School/3_OSU/Quarter_15/CS464/emscripten/tools/preprocessor.mjs - shell.html

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions