Skip to content
This repository has been archived by the owner on May 16, 2018. It is now read-only.

Zend_Controller_Dispatcher_Abstract::_formatName() inconsistent with Action name handling #440

Closed
divinoro opened this issue Oct 16, 2014 · 26 comments
Assignees
Milestone

Comments

@divinoro
Copy link

In normal case, URL is splited to [:module]/[controller]/[action], eg

domain.com/controller/action

In case of using unallowed chars, like "!" or "@", these are removed, so URL like

domain.com/!controller/action

is cleaned and used as

domain.com/controller/action

However, names of view folder is not claned, so entering

domain.com/!controller

will reult in calling "controller" controller and index action, trying to access

views/scripts/!controller/index.phtml

resulting in error 500, instead of 404 not found

Expecting behavior:

Approach should be consistent, so either keep exclamation mark in both (controller and controller folder) of remove unallowed chars also from view folder.

Why it's problem: some pages using #! to address dynamic pages using ajax calls, but crawlerrs are ignoring # and thats resulting in exceptions.

Thank you.
Ivan

@froschdesign
Copy link
Member

@divinoro

resulting in error 500

Is this error message from the ZF application or the web server?

@divinoro
Copy link
Author

Both are from webserver, but tha's not important :) I think important is unexpected behavior of ZF application. I'm just pointing out, that ZF is inconsistent between controller and action routing in this case..
I'm getting normal exceptions in both cases, of course.

@froschdesign
Copy link
Member

Both are from webserver, but tha's not important

The web server can give this error message and a ZF application can give this error message. There's a difference.

I think important is unexpected behavior of ZF application..

Can you provide an unit test for this? Thanks.

@divinoro
Copy link
Author

Unfotunately I have no idea how to run unit test or how to create it. Anyway, I tried to point this out, just in case someone will fall in such problems and will investigate couple of hours like me.

@froschdesign
Copy link
Member

Here is an unit test:

/**
 * @group GH-440
 * @dataProvider providerControllerNameDoesNotIncludeDisallowedCharacters
 */
public function testControllerNameDoesNotIncludeDisallowedCharacters($controllerName)
{
    $this->request->setControllerName($controllerName)
                  ->setActionName('index');

    $this->helper->setActionController(
        new Bar_IndexController(
            $this->request, $this->response, array()
        )
    );

    $this->assertEquals(
        'index/index.phtml', $this->helper->getViewScript()
    );
}

/**
 * Data provider for testControllerNameDoesNotIncludeDisallowedCharacters
 * @group GH-440
 * @return array
 */
public function providerControllerNameDoesNotIncludeDisallowedCharacters()
{
    return array(
        array('!index'),
        array('@index'),
        array('-index'),
    );
}

@froschdesign
Copy link
Member

@akrabat
Do you have an idea?

Maybe this one:

$controller = substr(
    $dispatcher->formatControllerName($request->getControllerName()),
    0,
    -10
);

https://github.com/zendframework/zf1/blob/master/library/Zend/Controller/Action/Helper/ViewRenderer.php#L845

@akrabat
Copy link
Contributor

akrabat commented Jan 5, 2015

That looks sane to me.

@froschdesign froschdesign self-assigned this Jan 5, 2015
@secu-ring
Copy link

There is a problem with the changed code part when the controller name don't have the word "Controller" as suffix. As I remember in ZF1 the controller names should be "Modulename_ControllerName" without the word "Controller". When I change a controller namer from maybe "Index_Index" to "IndexController" or even "Index_IndexController" the autoloader will not find the class.

The problem doesn't occur in version 1.12.9. When I change the code to the following, it works again.

$controller = $dispatcher->formatControllerName($request->getControllerName());

if (false !== strpos('controller', strtolower($controller))) {
    $controller = substr($controller, 0,-10);
}

Would be nice when You could fix this Problem.

Regards

@froschdesign
Copy link
Member

@secu-ring
Do you have overwritten the dispatcher? The standard dispatcher adds always the string "Controller".

@secu-ring
Copy link

@froschdesign
Yes, we're doing this. Than it makes sense that it won't work - we have to extend the View Renderer also to override these method.

Thanks for your hint.

@froschdesign
Copy link
Member

@secu-ring
I will add a condition.

@froschdesign
Copy link
Member

@secu-ring
See 988d293

@weierophinney
Copy link
Member

@secu-ring Can you post a note here indicating whether or not the patch from @froschdesign fixes the issue for you?

(Re-opening, as the issue was not resolved to satisfaction previously based on reports.)

@weierophinney weierophinney reopened this Jan 21, 2015
@secu-ring
Copy link

@weierophinney Yes the patch solved our problem.

anupdugar added a commit to anupdugar/zf1 that referenced this issue Feb 6, 2015
Zend Framework 1.12.10

- [1: isLast not working as expected in Zend&zendframework#95;Service&zendframework#95;Amazon&zendframework#95;SimpleDb&zendframework#95;Page](zendframework#1)
- [8: Zend&zendframework#95;Loader&zendframework#95;ClassMapAutoloader is not auto included when using Zend&zendframework#95;Loader&zendframework#95;AutoloaderFactory::factory](zendframework#8)
- [15: Zend&zendframework#95;Db&zendframework#95;Table&zendframework#95;Abstract::delete does not delete from dependent table](zendframework#15)
- [32: Zend&zendframework#95;Soap&zendframework#95;Client has no 'exceptions' flag.](zendframework#32)
- [62: Zend&zendframework#95;Validate&zendframework#95;EmailAddress->&zendframework#95;validateMXRecords() fails on Umlaut-Domains](zendframework#62)
- [187: Zend&zendframework#95;Rest&zendframework#95;Server does not properly handle optional parameters when anonymous (arg1, etc) parameters are passed in](zendframework#187)
- [322: Zend&zendframework#95;Validate&zendframework#95;Hostname: disallowed Unicode code point](zendframework#322)
- [324: SlideShare API change some tag names.](zendframework#324)
- [345: CallbackHandler throws warning if WeakRef-extension not installed](zendframework#345)
- [377: Zend&zendframework#95;Console&zendframework#95;Getopt: Missing required parameter consumes next option as its parameter value](zendframework#377)
- [400: PHPUnit contraints: use real class names to help classmap generators](zendframework#400)
- [426: Use relative filenames for &zendframework#95;validIdns for direct include in Zend&zendframework#95;Validate&zendframework#95;Hostname](zendframework#426)
- [434: Corrected type of property &zendframework#95;currentRoute](zendframework#434)
- [440: Zend&zendframework#95;Controller&zendframework#95;Dispatcher&zendframework#95;Abstract::&zendframework#95;formatName() inconsistent with Action name handling](zendframework#440)
- [441: Loosen regex to allow nested function calls in SQL](zendframework#441)
- [444: Update Zend&zendframework#95;Validate&zendframework#95;Hostname TLDs list to 2014102301 version](zendframework#444)
- [446: fix typo unkown -> unknown](zendframework#446)
- [448: fix travis ci build for php 5.2](zendframework#448)
- [449: Zend&zendframework#95;Date doesn't create correct date when seconds are missing from 8601 format](zendframework#449)
- [452: "fluent", not "fluid"](zendframework#452)
- [453: Zend&zendframework#95;Cache&zendframework#95;Backend&zendframework#95;Memcached looks at "bytes", but Couchbase 1.x returns "mem&zendframework#95;used"](zendframework#453)
- [456: Documentation of Zend&zendframework#95;Feed&zendframework#95;Pubsubhubbub&zendframework#95;Model&zendframework#95;ModelAbstract](zendframework#456)
- [458: Fixed bug in quoteInto with $count parameter and question sign in $value](zendframework#458)
- [461: CDATA section for category elements in RSS feed](zendframework#461)
- [465: Zend&zendframework#95;Currency creates invalid cache ids for values with fractions](zendframework#465)
- [467: debug&zendframework#95;backtrace() called twice when only once needed ](zendframework#467)
- [468: Zend&zendframework#95;Validate&zendframework#95;Hostname improvements](zendframework#468)
- [469: &zendframework#91;Zend&zendframework#95;Validate&zendframework#92; Testcase for zendframework#322](zendframework#469)
- [471: End of life for PHPUnit installation using pear](zendframework#471)
- [475: Zend Json Server Exception is missing the method name](zendframework#475)
- [478: Create .gitattributes to mirror archive { } in composer.json](zendframework#478)
- [480: Virtual machine doesn't install initial packages](zendframework#480)
- [483: Update copyright to 2015](zendframework#483)
- [484: Adds content headers on POST request in Zend&zendframework#95;Controller&zendframework#95;Request&zendframework#95;HTTP](zendframework#484)
- [487: Allow overriding cache id and tag validation in Zend&zendframework#95;Cache](zendframework#487)
- [488: Zend&zendframework#95;Dojo&zendframework#95;View&zendframework#95;Helper&zendframework#95;Dojo&zendframework#95;Container setCdnVersion error...](zendframework#488)
- [490: Added more specific return documentation for Zend&zendframework#95;Navigation Pages](zendframework#490)

# gpg verification failed.

Conflicts:
	README.md
	library/Zend/Application/Resource/Frontcontroller.php
	library/Zend/Application/Resource/Translate.php
	library/Zend/Barcode/Object/ObjectAbstract.php
	library/Zend/Controller/Router/Rewrite.php
	library/Zend/Db/Select.php
	library/Zend/EventManager/Filter/FilterIterator.php
	library/Zend/EventManager/GlobalEventManager.php
	library/Zend/Gdata/HttpAdapterStreamingProxy.php
	library/Zend/Mime/Part.php
	library/Zend/Mobile/Push/Message/Abstract.php
	library/Zend/Rest/Server.php
	library/Zend/Service/Rackspace/Files.php
	library/Zend/Service/SlideShare.php
	library/Zend/Test/PHPUnit/ControllerTestCase.php
	library/Zend/Validate/Hostname.php
	library/Zend/Version.php
@mirow
Copy link

mirow commented Mar 23, 2015

This seems to break compatibility with CamelCase controller names?

I have a controller class named "MetadataValidationController", and the view files are in a folder called "metadata-validation". This worked fine before, but resently it stopped working as Zend now looks for the view files in "metadavalidation" folder.

@froschdesign
Copy link
Member

I have a controller class named "MetadataValidationController", and the view files are in a folder called "metadata-validation".

This behaviour was never included in any unit tests – really shitty!

This worked fine before, but resently it stopped working as Zend now looks for the view files in "metadavalidation" folder.

Right, because the only word delimiters are "-" and ".".

@ianlayton
Copy link

@froschdesign I can't tell from you comment...is this something that will be 'fixed' to go back to the way it has worked in the past or is this something we will need to account for and adjust as a developer?

froschdesign added a commit to froschdesign/zf1 that referenced this issue Mar 27, 2015
@froschdesign
Copy link
Member

@mirow and @ianlayton
See: #537

Btw. Thanks for reporting! 👍

@akrabat
Copy link
Contributor

akrabat commented Mar 27, 2015

Should we roll a new release fairly quickly for this, @froschdesign ?

@froschdesign
Copy link
Member

@akrabat
Sure, but I see one more problem: #534
This should be fixed before we roll out the next release.

@bbrala
Copy link

bbrala commented Aug 10, 2015

Fun stuff, this does change how paths to views are resolved, and breaks current sites since it cannot find the views. Sure its a fix, but the merge breaks like, every site we built. Painfull "fix".

@akrabat
Copy link
Contributor

akrabat commented Aug 12, 2015

@bbrala Can you provide an example of what's broken for you?

@bbrala
Copy link

bbrala commented Sep 18, 2015

Ok, I've looked into this a little, and things started to fall apart in januari, before the code just user $request->getControllerName(); and that was it. I've put the old and new values in a list to show what is happening.

    echo '<br>Old name (pre 40dd702): ' . $request->getControllerName();;

    // Format controller name
    require_once 'Zend/Filter/Word/CamelCaseToDash.php';
    $filter     = new Zend_Filter_Word_CamelCaseToDash();
    $controller = $filter->filter($request->getControllerName());
    echo '<br>After CamelcaseFilter: ' . $controller;
    $controller = $dispatcher->formatControllerName($controller);
    echo '<br>After dispatcherformat: ' . $controller;
    if ('Controller' == substr($controller, -10)) {
        $controller = substr($controller, 0, -10);
    }
    echo '<br>new name: ' . $controller . ' <hr>';

Old name (pre 40dd702): Mainnav
After CamelcaseFilter: Mainnav
After dispatcherformat: MainnavController
new name: Mainnav

Old name (pre 40dd702): tekst
After CamelcaseFilter: tekst
After dispatcherformat: TekstController
new name: Tekst

Old name (pre 40dd702): head-html
After CamelcaseFilter: head-html
After dispatcherformat: HeadHtmlController
new name: HeadHtml

Hope that helps

@froschdesign
Copy link
Member

@bbrala

I've put the old and new values in a list to show what is happening.

Sorry, but where is the problem?

/**
 * @group GH-440
 * @dataProvider providerControllerNames
 */
public function testControllerNames($controllerName, $viewScriptDir)
{
   $this->request->setControllerName($controllerName)
                 ->setActionName('index');

   $this->helper->setActionController(
       new Bar_IndexController(
           $this->request, $this->response, array()
       )
   );

   $this->assertEquals(
       sprintf('%s/index.phtml', $viewScriptDir),
       $this->helper->getViewScript()
   );
}

/**
 * Data provider for testControllerNames
 * @group GH-440
 * @return array
 */
public function providerControllerNames()
{
    return array(
        array('Mainnav', 'mainnav'),
        array('tekst', 'tekst'),
        array('head-html', 'head-html'), // strange controller name!
    );
}

Tests passed

Did I miss something?

@bbrala
Copy link

bbrala commented Sep 18, 2015

That is pretty weird. The problem is the new name is different than the old one, breaking out view script paths. I'll double check this and see if i can expand a bit on my case. Maybe i echo the result to early.

@bbrala
Copy link

bbrala commented Sep 18, 2015

Ok, i cannot reproduce the problem why this was changed, i will check with the developer who fixed the issue (or was it xD) and see where it broke. It seems to have something to do with something like InschrijvenStap1 first translating into inschrijven-stap1 and now to inschrijven-stap-1. I don't have the today to check it more, but i'll try to make a proper demonstration later.

dgiotas pushed a commit to tripsta/zf1 that referenced this issue Jun 17, 2016
dgiotas pushed a commit to tripsta/zf1 that referenced this issue Jun 17, 2016
antonis179 pushed a commit to tripsta/zf1 that referenced this issue Jan 11, 2018
antonis179 pushed a commit to tripsta/zf1 that referenced this issue Jan 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants