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

[Filesystem] Fix makePathRelative when the original path does not end with a slash #40051

Closed
wants to merge 2 commits into from

Conversation

om4csaba
Copy link

@om4csaba om4csaba commented Feb 1, 2021

Q A
Branch? 4.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #25023
License MIT
Doc PR N/A

Maintain the path format after making relative.

History:
PR #4842 added a slash to the function output. According to the original explanation, "[...]to ensure all returned paths end with /."

Reason for change:
There is no need to add a slash, not even for operation upon directories. Maintaining the input format should enough for all file manipulation (symlink, copy, unset, etc.). There is a slight chance to introduce a break, but only if the path further altered after it changed to the relative. One possible mitigation would be to checking the input; it is a file or directory. But, the function in the current form does not access the filesystem. Adding an extra check will significantly slow it down and produce two different results when the $endPath exists, a directory, and the input does not have a trailing slash.

Test altered to reflect the changes.

@carsonbot
Copy link

Hey!

I see that this is your first PR. That is great! Welcome!

Symfony has a contribution guide which I suggest you to read.

In short:

  • Always add tests
  • Keep backward compatibility (see https://symfony.com/bc).
  • Bug fixes must be submitted against the lowest maintained branch where they apply (see https://symfony.com/releases)
  • Features and deprecations must be submitted against the 5.x branch.

Review the GitHub status checks of your pull request and try to solve the reported issues. If some tests are failing, try to see if they are failing because of this change.

When two Symfony core team members approve this change, it will be merged and you will become an official Symfony contributor!
If this PR is merged in a lower version branch, it will be merged up to all maintained branches within a few days.

I am going to sit back now and wait for the reviews.

Cheers!

Carsonbot

@nicolas-grekas
Copy link
Member

There is a slight chance to introduce a break, but only if the path further altered after it changed to the relative. One possible mitigation would be to checking the input; it is a file or directory

I think the check is worth it. is_dir is cached, so it won't slow down things much.

@om4csaba
Copy link
Author

I think the check is worth it. is_dir is cached, so it won't slow down things much.

You mean we will be checking the directory and adding a slash regardless of the input string?

I am assuming the method will still have output when a path not exists, then it can produce different output on subsequent run or different state of the filesystem:

$filesystem =new Symfony\Component\Filesystem\Filesystem();
$relative = $filesystem->makePathRelative('/path/to/project/resources', '/path/to/project');

if ($filesystem->exists('/path/to/project/resources')) {
    mkdir('/path/to/project/resources' );
}
echo $relative . PHP_EOL;

// -> '/path/to/project/resources'  if dir not exist
// -> '/path/to/project/resources/' if dir exist (or second run)

I believe it will create more problems than we currently have.
So I think changing the output is a better way forward.

@nicolas-grekas
Copy link
Member

I'm closing here because I think this can create troubles in existing codebases.
I agree it could have been a better, but the current behavior is too old to break.
Also, there are ways around (eg using the method on dirname($file))
Thanks for submitting.

@om4csaba om4csaba deleted the fix-makePathRelative branch January 31, 2022 01:02
@om4csaba
Copy link
Author

I understand the reasons.

Given the $relativePath is the output of the makePathRelative() method, and $endPath is the first argument, the following snippet removes the trailing slash if not present in the input:

if (!str_ends_with($endPath, '/')) {
    $relativePath =  rtrim($relativePath, '/');
}

@mvorisek
Copy link
Contributor

This needs to be definitely fixed, when a non-dir path is given (path not ending with /), the result must never have / appended. I agree this can imply BC break, bug the current impl. is simply wrong. Please reopen this PR or let me know if I or the original author should submit it newly.

@strarsis
Copy link

+1, I use this function to make a path to a stylesheet file (e.g. /srv/www/[...]/folder/app.css relative to another folder,
currently makePathRelative returns the path with a slash at the end (folder/app.css/).

@mvorisek
Copy link
Contributor

@nicolas-grekas Sensible fix like https://github.com/atk4/ui/blob/8f7a986c629a0adf3342c6d285bbef613fe52095/src/App.php#L655-L658 works /w current/buggy Symfony and /w this PR/fixed Symfony so fixing it should be fine as long as the developer was aware of this issue and counted with the possibility to be fixed in the future.

For me, it is clearly a bug in Symfony and it should be fixed sooner or later.

Can you please reconsider this PR, if not for 4.4, can it be integrated into 6.x?

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

Successfully merging this pull request may close these issues.

None yet

7 participants