Edgewall Software

Opened 13 years ago

Closed 13 years ago

#439 closed defect (fixed)

_speedups' glitch on Markup.escape(None, False) call

Reported by: cboos Owned by: hodgestar
Priority: minor Milestone: 0.7
Component: General Version: 0.6
Keywords: speedups Cc: trbs@…

Description

This problem was detected in #T10292 and tracked down to a call to Markup.escape(None, False) by trbs.

The "normal" behavior for such a call is:

  • genshi/tests/core.py

     
    8686        assert type(markup) is Markup
    8787        self.assertEquals(string, unescape(markup))
    8888
     89    def test_Markup_escape_None_noquotes(self):
     90        markup = Markup.escape(None, False)
     91        assert type(markup) is Markup
     92        self.assertEquals('', markup)
     93
    8994    def test_add_str(self):
    9095        markup = Markup('<b>foo</b>') + '<br/>'
    9196        assert type(markup) is Markup

But when the _speedups are present, that test fails with:

# PYTHONPATH=. python genshi/tests/core.py
......E........................................
======================================================================
ERROR: test_Markup_escape_None_noquotes (__main__.MarkupTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "genshi/tests/core.py", line 90, in test_Markup_escape_None_noquotes
    markup = Markup.escape(None, False)
TypeError: unicode() argument 2 must be string, not bool

The following change fixes the problem:

  • genshi/_speedups.c

     
    194194        return NULL;
    195195    }
    196196    if (PyObject_Not(text)) {
    197         return type->tp_new(type, args, NULL);
     197        return type->tp_new(type, PyTuple_New(0), NULL);
    198198    }
    199199    if (PyObject_TypeCheck(text, type)) {
    200200        Py_INCREF(text);

I'm not completely sure if we can get away with not doing a DECREF on that 0-tuple, so perhaps a safer fix would be:

  • genshi/_speedups.c

     
    194194        return NULL;
    195195    }
    196196    if (PyObject_Not(text)) {
    197         return type->tp_new(type, args, NULL);
     197        args = PyTuple_New(0);
     198        text = type->tp_new(type, args, NULL);
     199        Py_DECREF(args);
     200        return text;
    198201    }
    199202    if (PyObject_TypeCheck(text, type)) {
    200203        Py_INCREF(text);

Your take ;-)

Attachments (2)

g439-Markup_escape_fix.patch (1.1 KB) - added by cboos 13 years ago.
applies on 0.6.x and trunk
g439-Markup_escape_fix_2.patch (1.1 KB) - added by hodgestar 13 years ago.
Fix with check for failure allocated empty tuple.

Download all attachments as: .zip

Change History (7)

Changed 13 years ago by cboos

applies on 0.6.x and trunk

comment:1 Changed 13 years ago by hodgestar

  • Owner changed from cmlenz to hodgestar
  • Status changed from new to assigned

Changed 13 years ago by hodgestar

Fix with check for failure allocated empty tuple.

comment:2 Changed 13 years ago by hodgestar

I think we do need to DECREF the tuple and I think we also need to check that PyTuple_New doesn't fail. Updated patch attached. If you (cboos) agree I'll commit.

comment:3 Changed 13 years ago by cboos

I was under the impression that PyTuple_New(0) could never fail, but looking closer at the code in tupleobject.c it seems there could be pathological cases when this could happen (e.g. no zero tuple allocated so far and in an out of memory condition), so your change is indeed safer.

comment:4 Changed 13 years ago by trbs <trbs@…>

  • Cc trbs@… added

comment:5 Changed 13 years ago by hodgestar

  • Resolution set to fixed
  • Status changed from assigned to closed

Patch committed in r1168 and backported to 0.6.x in r1169. Thank again cboos.

Note: See TracTickets for help on using tickets.