WebFreak001 / FSWatch

A cross-platform folder & file watching library using win32, inotify or std.file
33 stars 8 forks source link

Fix wrong characters in path names in some situations #22

Closed andrejp88 closed 3 years ago

andrejp88 commented 3 years ago

When reading inotify_event objects, the code would do fromStringz on the name field of each event. That field might not exist, in which case the address of name is the start of the next inotify_event struct, if there is one. The first field there is wd, which in my case was always a small number (starts counting up from 0). Calling fromStringz on the 32-bit little-endian integer 1 gives you the string \x01, which is then passed to buildPath. The end result is you end up with control characters in the path string, or if you have a lot of watches (>20), they start showing up as normal printable characters (e.g. foo.txt%).

With this change, the file name is set to an empty string if len is 0, otherwise it's passed to fromStringz as before.

WebFreak001 commented 3 years ago

what exactly does it mean if len is 0? Is this an update that should be skipped? Does it make sense to pass an update without filename to the library user?

andrejp88 commented 3 years ago

According to the inotify man page:

The name field is present only when an event is returned for a file inside a watched directory; it identifies the filename within the watched directory. This filename is null-terminated, and may include further null bytes ('\0') to align subsequent reads to a suitable address boundary.

The len field counts all of the bytes in name, including the null bytes; the length of each inotify_event structure is thus sizeof(struct inotify_event)+len.

If the event is for the file/directory being watched, it doesn't include a name. If it's for a child of the directory being watched, the name is included.

In other words, you only get a name if you're watching a directory and something happened to a child of that directory.

WebFreak001 commented 3 years ago

wait if there is len that is the length of the string we could just slice the ptr, which would be safer anyway.

Do you think you wanna do and test that in this PR? (like .ptr[0 .. len].stripRight('\0'))

andrejp88 commented 3 years ago

Good call, just pushed it