On 5/13/20, Antoine Pitrou <solip...@pitrou.net> wrote:
>
> If you know of a system function which accepts filenames with embedded
> NULs (which probably means it also takes the filename length as a
> separate parameter), I'd be curious to know about it.

Windows is layered over the base NT system, which uses counted strings
and a root object namespace that reserves only the path separator,
backslash. Null characters are allowed, at least as far as the object
manager cares, but using them is a bad idea, if only because such
names aren't generally accessible in Windows. But let's look at an
example just for kicks.

When the object manager parses a path up to a Device object (e.g.
"\Device\NamedPipe"), the I/O manager takes over parsing the remaining
path, which calls the device driver's IRP_MJ_CREATE routine with the
remaining path. Whether or not a name with nulls is allowed depends on
the device driver -- or a filesystem driver if the device is mounted.

Almost all filesystem drivers reject a component name that contains
nulls as invalid. One exception is the named-pipe filesystem (NPFS).
NPFS doesn't disallow any characters. It even allows backslash in pipe
names since it doesn't support subdirectories, and if you check via
os.listdir('//./pipe'), you should see several Winsock pipes with
backslash in their name.

Creating a pipe with nulls in its name is impossible via WINAPI
CreateNamedPipeW. It requires native NtCreateNamedPipeFile, with the
name passed in an OBJECT_ATTRIBUTES record [1]. This system function
is undocumented, but just to show that it's possible in principle, I
created a pipe named "spam\x00eggs". We can query the name via
GetFileInformationByHandleEx: FileNameInfo [2], which returns a
counted string:

    >>> GetFileInformationByHandleEx(h, FileNameInfo)
    '\\spam\x00eggs'

The name is in the root path of the device, but we don't get the
fully-qualified name "\\Device\\NamedPipe\\spam\x00eggs". WINAPI
GetFinalPathNameByHandleW [3] can figure this out, at least for the
native NT path (from NtQueryObject). However, it works with
null-terminated strings, so the pipe name gets truncated as "spam":

    >>> flags = VOLUME_NAME_NT | FILE_NAME_OPENED
    >>> GetFinalPathNameByHandle(h, flags)
    '\\Device\\NamedPipe\\spam'

[1]: 
https://docs.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-_object_attributes
[2]: 
https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_name_info
[3]: 
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6EB4UMWV3TRMWL6RPY2KFU7PYJTYF4SY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to