# Extended 3.13 — src/fileUtilsWin.c: FILE_NAME_INFO trailing-NUL OOB write

Bug ref      : pharo.md §3.13
Severity     : HIGH (heap byte one past the buffer overwritten with WCHAR NUL)
File         : src/fileUtilsWin.c
Lines (HEAD) : ~64

## Problem

```c
int size = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
nameinfo = malloc(size);
... pGetFileInformationByHandleEx(fdHandle, FileNameInfo, nameinfo, size) ...
nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
```

`FileNameLength` is the actual stored length of the object name on
the filesystem (per Microsoft docs), not the buffer's capacity.
When the name fills the buffer exactly, `FileNameLength / sizeof(WCHAR)`
equals `MAX_PATH`; the trailing-NUL write lands one `WCHAR` past
the last writable slot, corrupting the malloc'd buffer's neighbour
in the heap.

## Fix

Clamp the NUL position to the buffer's index range.

```diff
diff --git a/plugins/FilePlugin/src/win/fileUtilsWin.c b/plugins/FilePlugin/src/win/fileUtilsWin.c
index e6623784a..3e5eb81bc 100644
--- a/plugins/FilePlugin/src/win/fileUtilsWin.c
+++ b/plugins/FilePlugin/src/win/fileUtilsWin.c
@@ -61,7 +61,14 @@ fileHandleType(HANDLE fdHandle) {
    }
    /* Check the name of the pipe: '\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master' */
    if (pGetFileInformationByHandleEx(fdHandle, FileNameInfo, nameinfo, size)) {
-       nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = L'\0';
+       {
+           /* FileNameLength reflects the stored object name; when the name
+            * fills the buffer exactly, the divide-by-2 NUL write lands one
+            * WCHAR past the end. Clamp to the last writable slot. */
+           DWORD nulIndex = nameinfo->FileNameLength / sizeof(WCHAR);
+           if (nulIndex >= MAX_PATH) nulIndex = MAX_PATH - 1;
+           nameinfo->FileName[nulIndex] = L'\0';
+       }
        p = nameinfo->FileName;
        //Check that the pipe name contains msys or cygwin
        if ((((wcsstr(p, L"msys-") || wcsstr(p, L"cygwin-"))) &&

```

## Test plan

- Obtain a file handle whose stored object name is exactly
  `MAX_PATH` wchars; call the surrounding function. Before:
  ASAN/Verifier reports a 2-byte heap-buffer-overflow. After: the
  name is truncated by one wchar; the function returns the
  truncated path.
- Normal name: unchanged.

## Risk notes

- Truncation is harmless for the audit's stated callers (used for
  logging/diagnostics). If a caller requires the exact full name,
  enlarge the buffer; for general code this clamp is enough.
