Skip to content

File and directory helpers on std::filesystem; mkdir() without the shell (#323) (4.2.31) - #787

Merged
ddehilster merged 1 commit into
masterfrom
feature/filesystem-323
Oct 15, 2026
Merged

ddehilster merged 1 commit into
masterfrom
feature/filesystem-323

Conversation

@ddehilster

Copy link
Copy Markdown
Member

Stage 1 of #323: the file and directory helpers move to std::filesystem. Moving them turned up real bugs.

NLP++ mkdir() (security + correctness). It built a shell command mkdir PATH and ran it with system(). Checked against 4.2.18 on Windows:

  • mkdir(G("$apppath") + "/made/plain") made nothing, because cmd reads /made as a switch. It still returned 1.
  • mkdir(base + "/x & echo pwned > pwned_323.txt") ran the echo and wrote the file.
  • A path with spaces broke.
  • It returned 1 whatever happened.

It now uses create_directories and returns whether the directory exists afterwards. Parent folders are made, and an existing folder returns 1. This applies to the interpreter and the compiled runtime.

dir_exists / make_dir / rm_dir in lite/mach.cpp were wrapped in #ifndef LINUX. On Linux and macOS, dir_exists was always true and make_dir/rm_dir did nothing. nlp.cpp relies on these for output and log folders.

kbdumptree() shelled out to cat on Linux and macOS. Every platform now concatenates in C++. It also closes the three part files first: they were read while still open, so their last buffered lines could be missing. The dump is byte-identical to 4.2.18's on Windows.

Also on std::filesystem: prim make_dir/rm_dir, file_size, file_exists (a directory no longer counts as an existing file on Linux), and nlp_engine's stat/mkdir/CreateDirectory.

Left alone on purpose:

  • the NLP++ system() builtin and the Python pass (shell use is their job);
  • dead Windows build paths (msdev, kb_release.bat, _OLDWAY_);
  • the third-party tagger in lextagger.cpp.

Tests:

  • New fixture tests/fs-ops with CI steps on Windows and Linux. It checks:
    • mkdir with plain, spaces, nested and existing paths, and that each folder exists;
    • that no pwned_323.txt appears;
    • that the kbdumptree dump holds the concept and attribute and ends with quit.
  • Local: 46/47 CI steps pass. The compiled-bridge step needs $GITHUB_WORKSPACE and always fails locally.
  • Full English Test: unchanged.
  • 20 analyzers × 21 inputs against 4.2.18: 0 differences.
  • The compiled fixture gives the same output as the interpreter.

Docs: a visualtext-files PR for the mkdir page follows. Batched: don't tag yet.

🤖 Generated with Claude Code

…ell (#323) (4.2.31)

Stage 1 of #323.
- NLP++ mkdir() ran a shell "mkdir PATH": a path with spaces, or on
  Windows with forward slashes, made nothing; a path with & or ; ran a
  command; and it always returned 1. It now uses create_directories and
  returns whether the directory exists.
- lite dir_exists/make_dir/rm_dir were #ifndef LINUX: on Linux and macOS
  dir_exists was always true and make_dir/rm_dir did nothing.
- kbdumptree() ran "cat" through the shell on Linux and macOS; all
  platforms now concatenate in C++, after closing the files being read.
- prim make_dir/rm_dir, file_size, file_exists (a directory no longer
  "exists" as a file on Linux), and nlp_engine stat/mkdir use
  std::filesystem.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant