Closed
Bug 332389
Opened 20 years ago
Closed 19 years ago
nsLocalFile::GetParent() doesn't return nsnull at top of volume
Categories
(Core :: XPCOM, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: jwkbugzilla, Assigned: jwkbugzilla)
Details
(Keywords: regression)
Attachments
(2 files, 3 obsolete files)
I was investigating why my extension would hang when traversing upwards through the directory tree. It came out that on Mac OS X nsIFile.parent always returns a value, even on top of the volume (I was testing with Firefox 1.5 on Mac OS X 10.3, but this code hasn't been touched in a while, so the problem should occur on trunk as well). This is a regression, bug 133617 refers to this issue as fixed. Execute the following code on Mac OS X:
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("/");
alert(file.parent.path)
This will show: /..
That's clearly not what it should be, see also comment in nsLocalFile::GetParent (http://lxr.mozilla.org/mozilla/source/xpcom/io/nsLocalFileOSX.cpp#1058). There should be an exception because file.parent should be null in this case. It seems that CFURLCreateCopyDeletingLastPathComponent doesn't return null on top of volume after all (I couldn't find any documentation stating what the return value of this function should be in such a case).
My hack to work around this problem was to break out of the loop when path is "/". But I think this should somehow be fixed in Gecko as well...
Updated•20 years ago
|
Summary: nsLocalFile::GetParent() doen't return nsnull at top of volume → nsLocalFile::GetParent() doesn't return nsnull at top of volume
Comment 1•19 years ago
|
||
http://darwinsource.opendarwin.org/10.4.2/CF-368.11/URL.subproj/CFURL.c
looks like CFURLCreateCopyDeletingLastPathComponent only returns NULL if the CFURL is a network URL with no path component.
| Assignee | ||
Comment 2•19 years ago
|
||
Robert, thanks for pointing me into the right direction. The way I read this code it will almost always do what we need (remove the last path component). The exceptions are the paths "", ".", ".." and "/" where it adds two dots. Since nsLocalFile cannot have relative paths, only the last case is problematic. We could add a special check for this case and return nsnull if mBaseRef is "/". A more general solution might be comparing the length of parentURLRef with the length of mBaseRef - we should only return a value if the former is smaller.
I am tending towards the second solution, the first one might be broken by changes in the Darwin code. The problem is - I cannot compile Firefox on a Mac. If I write a patch, will you be able to test/review it?
Comment 3•19 years ago
|
||
(In reply to comment #2)
>
> If I write a patch, will you be able to test/review it?
I touched this file last, so it should be kosher to do r=sayrer? / sr=bsmedberg?, so we get module owner approval.
| Assignee | ||
Comment 4•19 years ago
|
||
This will make the method only accept the result of CFURLCreateCopyDeletingLastPathComponent if it is shorter than what we had before - an increase in length indicates that there is no parent. I will also attach a diff with -w to make reviewing easier.
Assignee: nobody → trev
Status: NEW → ASSIGNED
Attachment #256466 -
Flags: superreview?
Attachment #256466 -
Flags: review?(sayrer)
| Assignee | ||
Updated•19 years ago
|
Attachment #256466 -
Flags: superreview? → superreview?(benjamin)
| Assignee | ||
Comment 5•19 years ago
|
||
Comment 6•19 years ago
|
||
Comment on attachment 256467 [details] [diff] [review]
Same patch with -w
>Index: nsLocalFileOSX.cpp
>
> }
>+ }
Indent the nested block, please.
Attachment #256467 -
Flags: review+
Comment 7•19 years ago
|
||
Comment on attachment 256467 [details] [diff] [review]
Same patch with -w
oops, wrong patch.
Attachment #256467 -
Flags: review+
Updated•19 years ago
|
Attachment #256466 -
Flags: review?(sayrer) → review+
Comment 8•19 years ago
|
||
Comment on attachment 256466 [details] [diff] [review]
Proposed patch
I'm increasingly thinking that we should replace most of the guts of nsLocalFileOSX with nsLocalFileUnix. In any case, I defer to Josh as mac guru.
Attachment #256466 -
Flags: superreview?(benjamin) → review?(joshmoz)
Comment on attachment 256466 [details] [diff] [review]
Proposed patch
Symlinks aren't getting resolved, but if they were then parent paths could potentially be longer than their children. To be safe, let's check for "/" as in addition to the path length check.
Attachment #256466 -
Flags: review?(joshmoz) → review-
| Assignee | ||
Comment 10•19 years ago
|
||
I don't see a point in checking for "/" *in addition* - we know that this path cannot have a parent, right? So if you are sure that this will always be the only problematic case then we can simply check for "/" and return nsnull here.
| Assignee | ||
Comment 11•19 years ago
|
||
This is untested again - I cannot compile on a Mac.
Attachment #256466 -
Attachment is obsolete: true
Attachment #256467 -
Attachment is obsolete: true
Attachment #257643 -
Flags: review?(joshmoz)
Comment 12•19 years ago
|
||
This is the same as the first patch, plus a warning fix. I like the first patch better afterall.
Attachment #257643 -
Attachment is obsolete: true
Attachment #257711 -
Flags: review+
Attachment #257643 -
Flags: review?(joshmoz)
Comment 13•19 years ago
|
||
There were also trailing CRs in the first patch, mine gets rid of that.
Comment 14•19 years ago
|
||
Patch v1 w/warning fix landed on trunk.
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Updated•19 years ago
|
Flags: in-testsuite?
| Assignee | ||
Comment 15•19 years ago
|
||
Proposed /mozilla/xpcom/tests/unit/test_bug332389.js file - tests whether following the .parent chain terminates.
Attachment #257957 -
Flags: review?(joshmoz)
Comment 16•19 years ago
|
||
Wladimir - how do you run that test?
Comment 17•19 years ago
|
||
Same way you run all xpcshell tests -- drop it in the location mentioned, do a |make| in xpcom/tests so that it gets propagated to the right locations in the objdir, and then run |make check| in xpcom/tests in your objdir.
Comment 18•19 years ago
|
||
That doesn't seem to be working in this case. I don't see any results.
Comment 19•19 years ago
|
||
Odd -- works for me.
However, when looking at the test I see:
for (var i = 0; i < 100; i++) {
if (f == null) {
terminated = true;
break;
}
try {
f = f.parent
}
catch (e) {
// Exception means we reached the top of a volume, terminate
f = null;
}
}
f.parent throwing an exception is not expected behavior. When f is the top directory, f.parent should be null and not throw, and on relooping the null will be detected and the test will pass. The try/catch is unnecessary -- just do |f = f.parent;| directly (and do include the semicolon).
Comment 20•19 years ago
|
||
Comment on attachment 257957 [details]
xpcshell testcase
I got it working now. Thanks!
Attachment #257957 -
Flags: review?(joshmoz) → review+
Comment 22•19 years ago
|
||
Could you remove the try/catch and add the semicolon, please, per comment 19?
Comment 23•19 years ago
|
||
try/catch removed, semicolon added, checked in
| Assignee | ||
Comment 24•19 years ago
|
||
Jeff, exception is the expected behavior on Windows. This test isn't Mac only. Now if you think that GetParent on Windows shouldn't throw an exception feel free to file a bug.
Josh, please check in the original patch, with the try/catch.
Comment 25•19 years ago
|
||
I've reverted the test to the original version, per comment 24.
Comment 26•19 years ago
|
||
(In reply to comment #24)
> Jeff, exception is the expected behavior on Windows.
The IDL documentation for nsIFile flatly contradict this, mentioning nothing about accessing the attribute throwing any exceptions and explicitly stating that |f.parent == null| when |f| represents the topmost directory:
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/xpcom/io/nsIFile.idl&rev=1.63&mark=324-327#320
I filed bug 373640 to fix this issue.
You need to log in
before you can comment on or make changes to this bug.
Description
•