[ 
http://issues.apache.org/jira/browse/MODPYTHON-98?page=comments#action_12360262 
] 

Graham Dumpleton commented on MODPYTHON-98:
-------------------------------------------

Okay, got a fix for this third issue.

The problem lies in python_handler() function in mod_python.c, namely it has:

    /* create a hahdler list object */
    request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);

    /* add dynamically registered handlers, if any */
    if (dynhle) {
        MpHList_Append(request_obj->hlo, dynhle);
    }

In the example I created, 'hle' was 0 and 'dynhle' was non 0. When 
MpHList_FromHLEntry() was called it was being given 0. In that function, it 
would then call hlist_copy on the null pointer causing it subsequently crash.

First attempt at a fix was to not call hlist_copy() if it was a null pointer, 
but if that was done, it would then crash in MpHList_Append() because you were 
trying to append to list when there wasn't actually a list to append to.

Thus, correct fix is to change the above code to:

    if (!hle)
    {
        /* create a handler list object from dynamically registered handlers */
        request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(dynhle);
    }
    else
    {
        /* create a handler list object */
        request_obj->hlo = (hlistobject *)MpHList_FromHLEntry(hle);

        /* add dynamically registered handlers, if any */
        if (dynhle) {
            MpHList_Append(request_obj->hlo, dynhle);
        }
    }

That is, if 'hle' is 0, create the handler list from 'dynhle' instead, else use 
existing code.

Note that case of both 'hle' and 'dynhle' was filtered out previously in the 
function.

I ran the test cases and it all passed with the above change. Test cases for 
the problems described in this bug report should perhaps be created.

> wrong handler supplied to req.add_handler() generates error
> -----------------------------------------------------------
>
>          Key: MODPYTHON-98
>          URL: http://issues.apache.org/jira/browse/MODPYTHON-98
>      Project: mod_python
>         Type: Bug
>   Components: core
>     Versions: 3.2, 3.1.4
>     Reporter: Graham Dumpleton

>
> The documentation for req.add_handler() states:
>   Note: There is no checking being done on the validity of the handler name. 
> If you pass this function an invalid handler it will simply be ignored.
> In other words, get the name of the handler wrong and it is supposed to just 
> ignore it. This is not actually the case, instead it will generate an 
> exception when it goes to process the handler:
>   Mod_python error: "PythonHandler example::handler_3"
>   Traceback (most recent call last):
>     File 
> "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/mod_python/apache.py",
>  line 291, in HandlerDispatch
>       arg=req, silent=hlist.silent)
>     File 
> "/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/mod_python/apache.py",
>  line 538, in resolve_object
>       raise AttributeError, s
>   AttributeError: module '/Users/grahamd/Sites/add_handler/example.py' 
> contains no 'handler_3'
> This can be seen with .htaccess file of:
>   SetHandler mod_python
>   PythonAccessHandler example
>   PythonHandler example::handler_1
>   PythonDebug On
> and example.py file containing:
>   from mod_python import apache
>   def accesshandler(req):
>     apache.log_error("accesshandler")
>     req.add_handler("PythonHandler","example::handler_3")
>     return apache.OK
>   def handler_1(req):
>     apache.log_error("handler_1")
>     req.content_type = 'text/plain'
>     req.write("HELLO")
>     return apache.OK
>   def handler_2(req):
>     apache.log_error("handler_2")
>     return apache.OK
> Either the documentation is wrong and an exception is desired, or more likely 
> this is an extension of the prior problem with hlist.silent as described as 
> being a problem in other ways in MODPYTHON-46.
> In that case the logic of SILENT/NOTSILENT was the wrong way around and it 
> was fixed by reversing the definitions of the two. In doing this though, it 
> didn't cover cases where a "silent" flag is passed to hlist_new() and 
> hlist_append() in the req_add_handler() function of requestobject.c.
> Specfically, there are calls to hlist_new() and hlist_append() in that 
> function:
>         hlist_append(self->request_rec->pool, self->hlo->head,
>                      handler, dir, 0);
>             hle = hlist_new(self->request_rec->pool, handler, dir, 0);
>             hlist_append(self->request_rec->pool, hle, handler, dir, 0);
> These should be written as:
>         hlist_append(self->request_rec->pool, self->hlo->head,
>                      handler, dir, SILENT);
>             hle = hlist_new(self->request_rec->pool, handler, dir, SILENT);
>             hlist_append(self->request_rec->pool, hle, handler, dir, SILENT);
> If this change were made, the code would then behaves conformant with the 
> documentation as far as being silent, however it highlights a further issue.
> This further issue is that although it is silent when the handler name is 
> wrong, this results in apache.DECLINED being returned for the handler that 
> couldn't be found. Because apache.DECLINED is returned, Apache will try and 
> interpret the URL again and if possible serve up a static file etc.
> For the above example code this then means that if "example.py" was used in 
> the URL, the browser gets back a response of:
>   HELLOfrom mod_python import apache
>   def accesshandler(req):
>     apache.log_error("accesshandler")
>     req.add_handler("PythonHandler","example::handler_3")
>     return apache.OK
>   def handler_1(req):
>     apache.log_error("handler_1")
>     req.content_type = 'text/plain'
>     req.write("HELLO")
>     return apache.OK
>   def handler_2(req):
>     apache.log_error("handler_2")
>     return apache.OK
> That is, the content as returned by handler_1(), followed by the contents of 
> the example.py file.
> If instead the URL wasn't 'example.py' but say 'other.py' with that not 
> existing, get back:
>   HELLO
>   OK
>   The requested URL /~grahamd/add_handler/foo.py was not found on this server.
>   Apache/2.0.51 (Unix) mod_python/3.2.5b Python/2.3 Server at localhost Port 
> 8080
> In some ways, this behaviour suggests that the behaviour whereby it raised an 
> exception was probably a better way of handling the situtation anyway. Thus, 
> maybe the documentation should instead be changed and the code left as is, or 
> at least the 0 arguments changed to be NOTSLIENT to make it more obvious what 
> it is doing.
> The other option is to change the code to use SILENT, but then document the 
> strange things that can result if the specified handler doesn't exist.
> Comments??????

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to