Closed
Bug 973538
Opened 11 years ago
Closed 11 years ago
Harden OS.Path.join() and OS.Path.winGetDrive()
Categories
(Toolkit Graveyard :: OS.File, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
mozilla30
People
(Reporter: gerard-majax, Assigned: gerard-majax)
References
Details
(Whiteboard: [systemsfe])
Attachments
(1 file, 9 obsolete files)
2.21 KB,
patch
|
gerard-majax
:
review+
|
Details | Diff | Splinter Review |
In bug 961745 we discovered that the precompilation cache step that happens during |make package| might fail because.
This is because the precompilation step does an import on JS files. With DownloadAPI.jsm, we have some code path that gets triggered and does a OS.Path.join(Constants.Path.profileDir, ...). However, during this specific step, Constants.Path.profileDir is undefined and we are okay with this.
But the OS.Path.join() code does not check this and fails because of a TypeError when trying to access the 'length' property of this undefined object, at http://hg.mozilla.org/mozilla-central/annotate/2bddbd180d2d/toolkit/components/osfile/modules/ospath_unix.jsm#l86
OS.Path.winGetDrive() exposes a similar behavior.
We propose to gracefully throw an exception in both methods when we have some undefined path components. This way, the try/catch mechanisms that lives in the precompilation cache code path should correctly handle the case.
Comment 1•11 years ago
|
||
Note that we need to maintain the semantics of throwing an error. As I understand gerard-majax' suggestion, we just want to throw a well-defined error instead of a random TypeError.
Updated•11 years ago
|
Component: General → OS.File
Product: Core → Toolkit
Assignee | ||
Comment 2•11 years ago
|
||
Please find attached a first patch. This patch does the job, but it seems to expose a nasty race condition that results in a segfault.
Assignee | ||
Comment 3•11 years ago
|
||
I tested a fix for the race in bug 973637. A Try build is pending for this bug with fix from bug 973637 applied: https://tbpl.mozilla.org/?tree=Try&rev=a7c14c769c45.
Status: NEW → ASSIGNED
Assignee | ||
Comment 4•11 years ago
|
||
(In reply to Alexandre LISSY :gerard-majax from comment #3)
> I tested a fix for the race in bug 973637. A Try build is pending for this
> bug with fix from bug 973637 applied:
> https://tbpl.mozilla.org/?tree=Try&rev=a7c14c769c45.
Try was green. Bug 973637 is about to get fixed.
Assignee | ||
Comment 5•11 years ago
|
||
Comment on attachment 8377142 [details] [diff] [review]
0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
Time to ask review, since bug 973637 will be fixed soon :)
Attachment #8377142 -
Flags: review?(dteller)
Comment 6•11 years ago
|
||
Comment on attachment 8377142 [details] [diff] [review]
0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
Review of attachment 8377142 [details] [diff] [review]:
-----------------------------------------------------------------
::: toolkit/components/osfile/modules/ospath_unix.jsm
@@ +83,3 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> for each(let i in arguments) {
Could you take the opportunity to make this function use rest arguments instead of |arguments|?
@@ +83,5 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> for each(let i in arguments) {
> + if (!i) {
> + throw new Error("undefined value in arguments");
"undefined path component", rather.
Also, make it a TypeError.
Same for Windows.
::: toolkit/components/osfile/modules/ospath_win.jsm
@@ +182,5 @@
> * includes "\\\\").
> */
> let winGetDrive = function(path) {
> + if (!path) {
> + throw new Error("path is undefined");
TypeError
Attachment #8377142 -
Flags: review?(dteller) → feedback+
Assignee | ||
Comment 7•11 years ago
|
||
(In reply to David Rajchenbach Teller [:Yoric] (please use "needinfo?") from comment #6)
> Comment on attachment 8377142 [details] [diff] [review]
> 0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
>
> Review of attachment 8377142 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: toolkit/components/osfile/modules/ospath_unix.jsm
> @@ +83,3 @@
> > // If there is a path that starts with a "/", eliminate everything before
> > let paths = [];
> > for each(let i in arguments) {
>
> Could you take the opportunity to make this function use rest arguments
> instead of |arguments|?
I'm not sure to get your point there :(
>
> @@ +83,5 @@
> > // If there is a path that starts with a "/", eliminate everything before
> > let paths = [];
> > for each(let i in arguments) {
> > + if (!i) {
> > + throw new Error("undefined value in arguments");
>
> "undefined path component", rather.
> Also, make it a TypeError.
>
> Same for Windows.
Done.
>
> ::: toolkit/components/osfile/modules/ospath_win.jsm
> @@ +182,5 @@
> > * includes "\\\\").
> > */
> > let winGetDrive = function(path) {
> > + if (!path) {
> > + throw new Error("path is undefined");
>
> TypeError
Done.
Flags: needinfo?(dteller)
Assignee | ||
Comment 8•11 years ago
|
||
(In reply to Alexandre LISSY :gerard-majax from comment #7)
> (In reply to David Rajchenbach Teller [:Yoric] (please use "needinfo?") from
> comment #6)
> > Comment on attachment 8377142 [details] [diff] [review]
> > 0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
> >
> > Review of attachment 8377142 [details] [diff] [review]:
> > -----------------------------------------------------------------
> >
> > ::: toolkit/components/osfile/modules/ospath_unix.jsm
> > @@ +83,3 @@
> > > // If there is a path that starts with a "/", eliminate everything before
> > > let paths = [];
> > > for each(let i in arguments) {
> >
> > Could you take the opportunity to make this function use rest arguments
> > instead of |arguments|?
>
> I'm not sure to get your point there :(
Done.
Flags: needinfo?(dteller)
Assignee | ||
Comment 9•11 years ago
|
||
Updating: should address all previous remarks (TypeError, using rest arguments)
Attachment #8377142 -
Attachment is obsolete: true
Attachment #8381423 -
Flags: review?(dteller)
Comment on attachment 8381423 [details] [diff] [review]
0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
Review of attachment 8381423 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good, thanks.
Note: switching from |arguments| to rest arguments was just a way to make the code more readable.
::: toolkit/components/osfile/modules/ospath_unix.jsm
@@ +83,3 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> + for each(let subpath in path) {
Nit: whitespace after |each|.
Attachment #8381423 -
Flags: review?(dteller) → review+
Assignee | ||
Comment 11•11 years ago
|
||
(In reply to David Rajchenbach Teller [:Yoric] (please use "needinfo?") from comment #10)
> Comment on attachment 8381423 [details] [diff] [review]
> 0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
>
> Review of attachment 8381423 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> Looks good, thanks.
> Note: switching from |arguments| to rest arguments was just a way to make
> the code more readable.
>
> ::: toolkit/components/osfile/modules/ospath_unix.jsm
> @@ +83,3 @@
> > // If there is a path that starts with a "/", eliminate everything before
> > let paths = [];
> > + for each(let subpath in path) {
>
> Nit: whitespace after |each|.
Done. I'm waiting on Try to make sure we break nothing.
Assignee | ||
Comment 12•11 years ago
|
||
Addressing latest nits, keeping r+.
Attachment #8381423 -
Attachment is obsolete: true
Attachment #8381625 -
Flags: review+
Assignee | ||
Comment 13•11 years ago
|
||
Looks like some code is breaking: https://tbpl.mozilla.org/php/getParsedLog.php?id=35234151&tree=Try#error1
David, I see some 'makeDir' messages with some payload that may contain null values. Should we address this in this bug, open a new bug and fix it before landing this one?
Flags: needinfo?(dteller)
Might as well do it now.
Flags: needinfo?(dteller)
Assignee | ||
Comment 15•11 years ago
|
||
We get into a join("/some/correct/path", ""). I suspect we want to handle this gracefully and not throw in this case.
Assignee | ||
Comment 16•11 years ago
|
||
Updated patch. Maybe we do not want to do the paths.push(subpath) if subpath.length == 0 ?
Attachment #8381625 -
Attachment is obsolete: true
Attachment #8381772 -
Flags: review?(dteller)
Comment on attachment 8381772 [details] [diff] [review]
0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
Review of attachment 8381772 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good, with a few trivial changes.
::: toolkit/components/osfile/modules/ospath_unix.jsm
@@ +83,4 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> + for each (let subpath in path) {
> + if (!subpath && subpath != "") {
Actually,
if (!subpath) {
}
covers both cases.
@@ +83,5 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> + for each (let subpath in path) {
> + if (!subpath && subpath != "") {
> + throw new TypeError("undefined path component");
Turns out it's "undefined or empty".
@@ +85,5 @@
> + for each (let subpath in path) {
> + if (!subpath && subpath != "") {
> + throw new TypeError("undefined path component");
> + }
> + if (subpath.length != 0 && subpath[0] == "/") {
Since we have already checked that |subpath| is not falsy, we can get rid of the |subpath.length| check.
::: toolkit/components/osfile/modules/ospath_win.jsm
@@ +141,4 @@
> let root;
> let absolute = false;
> for each(let subpath in path) {
> + if (!subpath && subpath != "") {
As for Unix.
Attachment #8381772 -
Flags: review?(dteller) → review+
Assignee | ||
Comment 18•11 years ago
|
||
I'll do the change, but I'm not sure to get your point. Some tests are failing because they are building a path with some components that are valid bug empty strings. From your first and second remarks, I get that you want to make them still invalid. Is this really what we want ?
OS.Path.join("a", "b", "c", ""); will throw ?
Btw Try still fails those tests on windows.
Flags: needinfo?(dteller)
Assignee | ||
Comment 19•11 years ago
|
||
Try is still failing on windows because of the same kind of behavior for winGetDrive("directory", "").
(In reply to Alexandre LISSY :gerard-majax from comment #18)
> I'll do the change, but I'm not sure to get your point. Some tests are
> failing because they are building a path with some components that are valid
> bug empty strings. From your first and second remarks, I get that you want
> to make them still invalid. Is this really what we want ?
>
> OS.Path.join("a", "b", "c", ""); will throw ?
>
> Btw Try still fails those tests on windows.
I'm just telling you that you're doing the same test twice so that we can remove the second test.
Flags: needinfo?(dteller)
Assignee | ||
Comment 21•11 years ago
|
||
(In reply to David Rajchenbach Teller [:Yoric] (please use "needinfo?") from comment #20)
> (In reply to Alexandre LISSY :gerard-majax from comment #18)
> > I'll do the change, but I'm not sure to get your point. Some tests are
> > failing because they are building a path with some components that are valid
> > bug empty strings. From your first and second remarks, I get that you want
> > to make them still invalid. Is this really what we want ?
> >
> > OS.Path.join("a", "b", "c", ""); will throw ?
> >
> > Btw Try still fails those tests on windows.
>
> I'm just telling you that you're doing the same test twice so that we can
> remove the second test.
Sorry, not totally awake yet :)
I've fixed the changes, that Try [https://tbpl.mozilla.org/?tree=Try&rev=9e9ca15eac41] should be okay now, and suiting your remarks. Thanks !
Assignee | ||
Comment 22•11 years ago
|
||
Updating the fix according to feedback.
Attachment #8381772 -
Attachment is obsolete: true
Attachment #8382115 -
Flags: review+
Assignee | ||
Comment 23•11 years ago
|
||
Sorry again, but the suggestion of '!!subpath == false' is of course making xpcshell tests failing, because |!!"" == false| is obviously true.
We really need to decide what we want. Do we want to throw on an empty but valid string?
For reference, Python's behavior:
> >>> print os.path.join("a","b","c")
> a/b/c
> >>> print os.path.join("a","b","c", "")
> a/b/c/
> >>>
Assignee | ||
Comment 24•11 years ago
|
||
David, I think we should not throw on empty string. What's your decision, based on the previous comment?
Flags: needinfo?(dteller)
Assignee | ||
Comment 25•11 years ago
|
||
Updated: checking explicitely for null and undefined values.
Attachment #8382115 -
Attachment is obsolete: true
Attachment #8382200 -
Flags: review+
Assignee | ||
Comment 26•11 years ago
|
||
Updated: explicitely checking for null || undefined, and make error message not only about undefined.
Attachment #8382200 -
Attachment is obsolete: true
Attachment #8382213 -
Flags: review+
Comment on attachment 8382213 [details] [diff] [review]
0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
Review of attachment 8382213 [details] [diff] [review]:
-----------------------------------------------------------------
I have no strong position on empty strings, do whichever you prefer.
Please simplify your tests, though.
::: toolkit/components/osfile/modules/ospath_unix.jsm
@@ +83,4 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> + for each (let subpath in path) {
> + if (subpath == null || subpath == undefined) {
if (subpath == null)
is sufficient, as undefined == null
Assignee | ||
Comment 28•11 years ago
|
||
Updating: fixing a typo (subpath instead of path)
Attachment #8382213 -
Attachment is obsolete: true
Attachment #8382247 -
Flags: review+
Assignee | ||
Comment 29•11 years ago
|
||
Updated: only testing against null.
Attachment #8382247 -
Attachment is obsolete: true
Attachment #8382249 -
Flags: review+
Comment 30•11 years ago
|
||
Comment on attachment 8382249 [details] [diff] [review]
0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
Review of attachment 8382249 [details] [diff] [review]:
-----------------------------------------------------------------
::: toolkit/components/osfile/modules/ospath_unix.jsm
@@ +83,3 @@
> // If there is a path that starts with a "/", eliminate everything before
> let paths = [];
> + for each (let subpath in path) {
for (let subpath of path) {
Assignee | ||
Comment 31•11 years ago
|
||
(In reply to Brandon Benvie [:benvie] from comment #30)
> Comment on attachment 8382249 [details] [diff] [review]
> 0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
>
> Review of attachment 8382249 [details] [diff] [review]:
> -----------------------------------------------------------------
>
> ::: toolkit/components/osfile/modules/ospath_unix.jsm
> @@ +83,3 @@
> > // If there is a path that starts with a "/", eliminate everything before
> > let paths = [];
> > + for each (let subpath in path) {
>
> for (let subpath of path) {
Why ? What difference does it makes ?
Comment 32•11 years ago
|
||
(In reply to Alexandre LISSY :gerard-majax from comment #31)
> (In reply to Brandon Benvie [:benvie] from comment #30)
> > Comment on attachment 8382249 [details] [diff] [review]
> > 0001-Bug-973538-Throw-an-exception-on-undefined-values-fo.patch
> >
> > Review of attachment 8382249 [details] [diff] [review]:
> > -----------------------------------------------------------------
> >
> > ::: toolkit/components/osfile/modules/ospath_unix.jsm
> > @@ +83,3 @@
> > > // If there is a path that starts with a "/", eliminate everything before
> > > let paths = [];
> > > + for each (let subpath in path) {
> >
> > for (let subpath of path) {
>
> Why ? What difference does it makes ?
`for each` is deprecated Mozilla-specific JS syntax. for-of is ES6 and accomplishes the same thing, so it is preferable. We're trying to not add new uses of Mozilla-specific JS extensions.
Assignee | ||
Comment 33•11 years ago
|
||
Updating: use "for of" construct.
Attachment #8382249 -
Attachment is obsolete: true
Attachment #8382337 -
Flags: review+
Updated•11 years ago
|
Flags: needinfo?(dteller)
Assignee | ||
Comment 34•11 years ago
|
||
Bug 973637 got r+ and should be able to land soon.
Assignee | ||
Comment 35•11 years ago
|
||
Bug 973637 landed, we can go with this one now.
Keywords: checkin-needed
Comment 36•11 years ago
|
||
Keywords: checkin-needed
Whiteboard: [systemsfe] → [systemsfe][fixed-in-fx-team]
Comment 37•11 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Whiteboard: [systemsfe][fixed-in-fx-team] → [systemsfe]
Target Milestone: --- → mozilla30
Updated•1 years ago
|
Product: Toolkit → Toolkit Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•