# N02 — NewFilePlugin Unix NewDirectory_open: opendir() called on non-NUL-terminated path

Bug ref      : pharo-12 only
Severity     : HIGH (every directory open with a non-NUL-terminated path string;
                     OOB read of attacker-influenced bytes)
File         : plugins/NewFilePlugin/src/unix/UnixFile.c
Lines (HEAD) : 43-55

## Problem

```c
NewDirectory_t *
NewDirectory_open(const char *path, size_t pathSize)
{
    char *cpath = makeCStringWithFixedString(path, pathSize);  // makes a copy
    DIR *handle = opendir(path);                                // uses original
    free(cpath);
    if(!handle)
        return NULL;
    ...
}
```

`cpath` is built precisely to give `opendir` a NUL-terminated copy, but
the next line passes `path` (the raw caller buffer) anyway. `opendir`
reads bytes until it finds a NUL, which on a non-NUL-terminated buffer
extends into adjacent memory. This is the same defect class as audit
§3.23 (SocketPlugin `stat()` on a non-NUL-terminated image buffer).

This is also internally inconsistent: `NewDirectory_create`,
`NewDirectory_removeEmpty`, `NewFile_deleteFile`, and `NewFile_open`
in the same file all correctly use `cpath`. Only `NewDirectory_open`
falls through to `path`.

## Fix

```diff
diff --git a/plugins/NewFilePlugin/src/unix/UnixFile.c b/plugins/NewFilePlugin/src/unix/UnixFile.c
index bb7a747b0..1027772f7 100644
--- a/plugins/NewFilePlugin/src/unix/UnixFile.c
+++ b/plugins/NewFilePlugin/src/unix/UnixFile.c
@@ -44,7 +44,7 @@ NewDirectory_t *
 NewDirectory_open(const char *path, size_t pathSize)
 {
     char *cpath = makeCStringWithFixedString(path, pathSize);
-    DIR *handle = opendir(path);
+    DIR *handle = opendir(cpath);
     free(cpath);
     if(!handle)
         return NULL;
```

## Test plan

- Pass a `path` argument that is a substring of a longer buffer (with no
  NUL after `pathSize`). Before: opendir reads past the intended path;
  ASAN reports `heap-buffer-overflow` in `strlen`/`__opendir_common`.
  After: clean.
- Normal NUL-terminated path: unchanged (cpath equals path bytes plus a
  single trailing NUL).

## Risk notes

- One-character variable change. Cannot regress.
- Matches the local convention used by every other function in this
  file.
