Open Bug 1428304 Opened 7 years ago Updated 2 years ago

mozfile.remove() incorrectly removes the contents of symlinked directories on Windows

Categories

(Testing :: Mozbase, enhancement, P3)

Version 3
Unspecified
Windows
enhancement

Tracking

(Not tracked)

People

(Reporter: standard8, Unassigned)

References

Details

In another bug I was investigating issues with shutil.rmtree on Windows. I saw clobber.py's use of mozfile.remove() and attempted to use that, but it gave the same problems as rmtree. Switching to use `winrm.exe` as clobberer does, handles the issue correctly. In this case I was testing removing the node_modules directory. In the directory, there's a couple of symlinked directories: node_modules/eslint-plugin-mozilla node_modules/eslint-plugin-spidermonkey-js These point to their respective directories in tools/lint/eslint. They are symlinks that are set up by npm install. Running mozfile.remove('/path/to/node_modules') causes the contents of: tools/lint/eslint/eslint-plugin-mozilla tools/lint/eslint/eslint-plugin-spidermonkey-js to be removed as well as the entirety of node_modules when run on Windows. Running the same code on Mac works correctly.
mozfile.remove uses os.path.islink to determine if the path is a symlink. os.path.islink did not support Windows native symlinks until Python 3.2. What version of Python are you using?
Flags: needinfo?(standard8)
I'd have been using Python 2.7, since that's the standard baseline that Mozilla supports at the moment.
Flags: needinfo?(standard8)
Priority: -- → P3
The line of code referenced in comment 1 is here: https://dxr.mozilla.org/mozilla-central/rev/c291143e24019097d087f9307e59b49facaf90cb/testing/mozbase/mozfile/mozfile/mozfile.py#214 I wrote some sample code for detecting symlinks on Windows and tested it locally: ``` import platform INVALID_FILE_ATTRIBUTES = -1 FILE_ATTRIBUTE_REPARSE_POINT = 0x400 if platform.system() == 'Windows': import ctypes def is_link(path): path_buf = ctypes.create_unicode_buffer(path) return ctypes.windll.kernel32.GetFileAttributesW(path_buf) & FILE_ATTRIBUTE_REPARSE_POINT == FILE_ATTRIBUTE_REPARSE_POINT else: import os is_link = os.path.islink ``` It should be straightforward to incorporate this into mozfile.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.