Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-5582] Changed NSString.appendingPathComponent implementation on Lin… #1294

Merged
merged 1 commit into from
Nov 8, 2017
Merged

[SR-5582] Changed NSString.appendingPathComponent implementation on Lin… #1294

merged 1 commit into from
Nov 8, 2017

Conversation

ogres
Copy link
Contributor

@ogres ogres commented Nov 3, 2017

Resolves SR-5582

Changed NSString.appendingPathComponent implementation on Linux to match Darwin's

Fixed following issues where path.appendingPathComponent(component) would produce incorrect result:

path was empty and component did not start with /
or
path ended with / and component started with /

Before:

"/tmp/".appendingPathComponent("scratch.tiff") == "/tmp//scratch.tiff"
"".appendingPathComponent("scratch.tiff") == "/scratch.tiff"

After:

"/tmp/".appendingPathComponent("scratch.tiff") == "/tmp/scratch.tiff"
"".appendingPathComponent("scratch.tiff") == "scratch.tiff"

Added test_appendingPathComponent.
Moved test_deletingLastPathComponent close to related tests ( test_stringByAppendingPathExtension, test_deletingPathExtension)

Before this commit, NSString and String had their own implementation and code was duplicated.
In this change, NSString._stringByAppendingPathComponent directly calls String's internal function ( _swiftObject._stringByAppendingPathComponent ). Is this okay? @phausler

Copy link
Contributor

@alblue alblue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be useful if the commit message was a bit more descriptive, such as fixing the issue with / as a suffix, for example.

return "/" + str
}
if self == "/" {
if hasSuffix("/") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the isEmpty check should become before the self check, as it was before. Is there a reason why they were reversed?

The change to use hasSuffix is a good one, though, and will work in the self == "/" case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the isEmpty check should become before the self check, as it was before. Is there a reason why they were reversed?

I thought about it and I think appending a path component to an empty string is less common than appending to actual path, therefore, cases where isEmpty evaluates true should be fewer. Most cases will be handled in hasSuffix and last line of the function ( self + "/" + str )

What do you think about it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That may be the case, but we now have different short-circuit behaviour on both platforms, and it's really unrelated to this change (which is to fix the bug where appending something onto a string that ends with / results in two // I suspect). I would prefer it to keep it as is (and minimise diffs) in order to fix this bug, and then if it is decided that the re-ordering of the test cases makes sense then it can be done. Several bugs have made it through to production where code was rewritten as:

a->something();
if (a==NULL) { abort(); }

because a compiler could 'prove' that dereferencing something implied that the variable could never be null, since otherwise would be undefined behaviour and thus the if check could be compiled out completely from the code.

While Swift doesn't suffer from this, the isEmtpy check could easily be handling such special-cases (now or in the future) and the re-ordering based on 'a thought' probably isn't the right way to tackle this issue.

Can you commit without the re-ordering on the checks so that you're just fixing the bug, and then squash all the commits so that we don't have interim mess getting in the way? We can then propose via separate PR/bug report that reordering the cases is desirable, with data to back up that particular part of the claim.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alblue ok, what about calling Swift.String's internal function from NSString.append... ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense for the calls to be de-duplicated as you have done now; but @parkera or @phausler are the ones to definitively make that call. For me, the less duplicated code we have, the better :)

@@ -77,7 +77,6 @@ class TestNSString : XCTestCase {
("test_initializeWithFormat", test_initializeWithFormat),
("test_initializeWithFormat2", test_initializeWithFormat2),
("test_initializeWithFormat3", test_initializeWithFormat3),
("test_deletingLastPathComponent", test_deletingLastPathComponent),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is just moving the contents rather than changing, please leave it here. If necessary, you can add the test_appendingPathComponent above the test_deletingLastPathComponent to minimise the diffs.

@@ -753,50 +754,6 @@ class TestNSString : XCTestCase {
}
}

func test_deletingLastPathComponent() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, don't delete this method and move it elsewhere in the file. If you want to keep the new test with this one, insert it above here.

@ogres
Copy link
Contributor Author

ogres commented Nov 3, 2017

Added information about fixes to commit message;
Changed TestNSString.swift to minimise the diffs.

…ux to match Darwin's.

Fixed following issues where path.appendingPathComponent(component) would produce incorrect result:

path was empty and component did not start with /
or
path ended with / and component started with /
@ogres
Copy link
Contributor Author

ogres commented Nov 3, 2017

Moved isEmpty checks at the beginning of the function

@alblue
Copy link
Contributor

alblue commented Nov 6, 2017

@swift-ci please test

@ogres
Copy link
Contributor Author

ogres commented Nov 8, 2017

@alblue @parkera could you invoke swift-ci to merge? I do not have access for it

@ianpartridge
Copy link
Collaborator

@swift-ci please test and merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants