? Pending

User tests: Successful: Unsuccessful:

avatar regularlabs
regularlabs
13 Nov 2018

When using the 'Install from URL' (or any extension using that functionality), downloads the package file, it will try to find a suitable file name to use to store in the tmp folder.
In most cases the filename is taken from the header information from the file.

However, if that information is not available, it will try to create a filename based on the url.
It does this using the getFilenameFromUrl() method.

So if the file is:

https://www.some-domain.com/downloads/foobar.zip

Then the filename will be foobar.zip.

That's all great.
However, what if the url is:

https://www.some-domain.com/downloads/file.php?file=foobar

Then the filename will be file.php?file=foobar.
Or even worse:

https://www.some-domain.com/downloads/?file=foobar

Will result in the filename ?file=foobar.

If this happens, then the next step in the process, the unpacking of the package, will fail miserably. As the special characters in the filename will cause kittens to die.

But there is another issue with the getFilenameFromUrl() method.
It is only used by the parent InstallerHelper class code (even though it is a public method).
And this is the code where it is used:

$target = $tmpPath . '/' . self::getFilenameFromUrl($url);

But the getFilenameFromUrl() method will return a false if it can't find a filename for whatever reason.
So that would result in the filename 'false'... Not good.

Summary of Changes

So the PR makes the whole getFilenameFromUrl() method smarter.

  1. It will trim and replace any special characters with underscores.
    So https://www.some-domain.com/downloads/?file=foobar will result in file_foobar.
  2. It will fall back to and return a unique id (like ``) if there is no file name found for whatever reason.

Testing Instructions

This is hard to test in real life, as this code only gets triggered when stuff is not as it should be (no correct header information and such).
So probably best to test this through test suits passing dummy (fake) data to it.
If you can do that, I don't have to explain :)

Documentation Changes Required

https://api.joomla.org/cms-3/classes/Joomla.CMS.Installer.InstallerHelper.html
The return value of the getFilenameFromUrl() mothod has changed, as it now will always return a string. No more false value.
So:

getFilenameFromUrl(string $url) : mixed

Becomes:

getFilenameFromUrl(string $url) : string

And:

Response
mixed String filename or boolean false if failed

Becomes:

Response
string Clean version of the filename or a unique id
avatar regularlabs regularlabs - open - 13 Nov 2018
avatar regularlabs regularlabs - change - 13 Nov 2018
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 13 Nov 2018
Category Libraries
avatar regularlabs regularlabs - change - 13 Nov 2018
Labels Added: ?
avatar regularlabs
regularlabs - comment - 13 Nov 2018

Thanks

avatar Quy
Quy - comment - 14 Nov 2018

I have tested this item successfully on 9327356


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/23066.

avatar Quy Quy - test_item - 14 Nov 2018 - Tested successfully
avatar PhilETaylor
PhilETaylor - comment - 14 Nov 2018

In the absence of real unit tests...

https://3v4l.org/W0iUJ

var_dump(getFilenameFromUrl('THIS IS NOT A URL'));
// result = 5bebb0a10012b
var_dump(getFilenameFromUrl('https://example.com/this____or_that______.zip?dlid=asd'));
//result = this_or_that_.zip_dlid_asd
var_dump(getFilenameFromUrl('https://example.com/this____or_that______.zip?dlid=asd____a_a_a__b__b__B'));
// result =this_or_that_.zip_dlid_asd_a_a_a_b_b_B
var_dump(getFilenameFromUrl('https://www.some-domain.com/downloads/file.php?file=foobar'));
//result = file.php_file_foobar
var_dump(getFilenameFromUrl('https://www.some-domain.com/downloads/file.zip?slid=123'));
//result = file.zip_slid_123
 var_dump(getFilenameFromUrl('https://www.some-domain.com/downloads/?file=foobar'));
//result = file_foobar

Are you happy with all those ? If so then I'll mark this as a successful test.

avatar regularlabs
regularlabs - comment - 14 Nov 2018

Yep. Happy with those.

avatar PhilETaylor
PhilETaylor - comment - 14 Nov 2018

I have tested this item successfully on 9327356

As per my comment above


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/23066.

avatar PhilETaylor PhilETaylor - test_item - 14 Nov 2018 - Tested successfully
avatar regularlabs
regularlabs - comment - 14 Nov 2018

?

avatar PhilETaylor
PhilETaylor - comment - 14 Nov 2018

Just seen this one in a myJoomla.com audit:

screenshot 2018-11-14 at 09 29 11

This is the kind of thing that this PR fixes :)

New filename would be

engagebox_view_Item_task_download_format_raw_id_181_dummy_my.zip_amp_dlid_2aae6240522a6fd4303597e09907013b

happy with that?

dlid changes to protect the innocent ;)

avatar regularlabs
regularlabs - comment - 14 Nov 2018

Yes. Seems fine.
I personally don't care about the filename that much, as long as it works.
And special chars can break stuff.
So that new filename seems ok to me.

avatar regularlabs
regularlabs - comment - 14 Nov 2018

I could add some code to trim the name down to a max length. But that hasn't been an issue as far as I know.

avatar rdeutz
rdeutz - comment - 14 Nov 2018

@regularlabs could you rebase your branch with staging to get travis green, thanks

avatar zero-24
zero-24 - comment - 14 Nov 2018

Merging thanks!

avatar zero-24 zero-24 - change - 14 Nov 2018
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2018-11-14 11:50:45
Closed_By zero-24
avatar zero-24 zero-24 - close - 14 Nov 2018
avatar zero-24 zero-24 - merge - 14 Nov 2018
avatar regularlabs
regularlabs - comment - 14 Nov 2018

Great :)

Hope #23065 gets merged quickly too, as that one is even more important (helps prevent this getFilenameFromUrl() getting called at all).

avatar zero-24
zero-24 - comment - 14 Nov 2018

merged.

avatar zero-24
zero-24 - comment - 14 Nov 2018

Thanks!

avatar regularlabs
regularlabs - comment - 15 Nov 2018

?

avatar PhilETaylor
PhilETaylor - comment - 15 Nov 2018

Another example seen in myJoomla.com today

File found in /tmp was

/tmp/index.php?option=com_dms&task=doc_download&id=78&updater=true

var_dump(getFilenameFromUrl('https://example.com/index.php?option=com_dms&task=doc_download&id=78&updater=true'));

// result = index.php_option_com_dms_task_doc_download_id_78_updater_true

Add a Comment

Login with GitHub to post a comment