Name length protection needed in TCanvas.Print?

Dear experts,

The below piece of code leads to horrible segfaults in both v5.18.00 and v5.19/03 (from svn), both on a linux machine and on a MacBook running OS X 10.5.2.

Interestingly, the segfault occurs at a name length of 264 in v5.19 but at a length of 263 in v5.18. I cannot reproduce this problem running straight from a ROOT macro. Actually, playing with this, I just noticed that changing the code into the second version below moves the problem in v5.19 to a name length of 278. So this looks like a stack problem in the Python part to me but I’m not sure how exactly this works in Python.

Is this reproducible for others as well?

Thanks,
Jeroen

#!/usr/bin/env python

from ROOT import gROOT
from ROOT import TCanvas

gROOT.Reset()
gROOT.SetBatch(True)

canvas = TCanvas("canvas")

for i in xrange(250, 300):

    name = "%s.pdf" % (i * "a")

    print "Trying name of length %d" % len(name)

    canvas.Print(name)
#!/usr/bin/env python

from ROOT import gROOT
from ROOT import TCanvas

gROOT.Reset()
gROOT.SetBatch(True)

canvas = TCanvas("canvas")

for i in xrange(250, 300):

    tmp = i * "a"
    name = "%s.pdf" % tmp

    print "Trying name of length %d" % len(name)

    canvas.Print(name)

Jeroen,

crashes just as hard with .C for me. I’m looking at the following in TPDF.cxx, which appears to be incorrect (unless I’m missing something basic):

if (fLenBuffer+len >= fSizBuffer) { fBuffer = TStorage::ReAllocChar(fBuffer, 2*fSizBuffer, fSizBuffer); fSizBuffer = 2*fSizBuffer; } strcpy(fBuffer + fLenBuffer, str); fLenBuffer += len;
here, the code assumes that 2*fSizBuffer will be larger than fLenBuffer+len+1 when fLenBuffer+len is larger/equal than/to fSizBuffer.

The starting value of fSizBuffer is 250, so with strings that have a length of around that value, 2*fSizBuffer is not large enough to contain fLenBuffer+len+1, if fLenBuffer itself has been built-up to close to fSizBuffer. Then, strcpy starts scribbling in memory that is not owned by the application and things go wrong from there. Since it is a memory overwrite, the actual problem can show up anywhere.

I’ll post a savannah later, after I’ve distilled it some more.

Cheers,
Wim

Jeroen,

I left a savannah here: https://savannah.cern.ch/bugs/index.php?36453

Cheers,
Wim

Thanks for looking at that Wim. You’re right, it crashes from cint too, but it seems less predictable/reproducible compared to the Python version. Anyway, thanks for submitting this one.

Jeroen

Hi Wim,
I am taking care of this via the Savannah report. Thanks to have reported this. I will let you know as soon as it will be fixed.

Olivier

now fixed. See: savannah.cern.ch/bugs/index.php?36453