You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by bu...@apache.org on 2002/02/17 02:00:51 UTC

DO NOT REPLY [Bug 6506] New: - XSLT VariableStack shift results in invalid pointer and crash

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6506>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6506

XSLT VariableStack shift results in invalid pointer and crash

           Summary: XSLT VariableStack shift results in invalid pointer and
                    crash
           Product: XalanC
           Version: 1.3.x
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: XalanC
        AssignedTo: xalan-dev@xml.apache.org
        ReportedBy: afanello@centor.com


This bug was found while using the XalanTransformer class from my own project. 
I was unable to reproduce it with TestXSLT, but I have been able to discover 
the bug programmatically and put together a kludge that works around it.

In the XSLT method VariablesStack::findXObject(), it starts off with the line:

	StackEntry* const  theEntry =
		findEntry(name, fIsParam, fSearchGlobalSpace);

This results in a pointer to an element in the "std::vector<StackEntry> 
m_stack" member variable.

Toward the end of the findXObject() method, is the code:

	// We need to set up a stack frame for the variable's execution...
	typedef StylesheetExecutionContext::PushAndPopContextMarker
			PushAndPopContextMarker;

	const PushAndPopContextMarker theContextMarkerPushPop(executionContext);

This variable invocation ultimately makes a call to m_stack.push_back(). At 
some point, when depends on the STL implementation, this push_back() call 
results in the contents of the vector being copied into a new block of memory - 
invalidating all iterators (and pointers) to the data.

The findXObject() method then goes on to utilizing the now invalid pointer:

	theEntry->setValue(theNewValue);
	theEntry->activate();

Under most implementations, I suppose that the old data is still there and thus 
we have been lucky. However, this crashed on a Release build under Visual 
C++.NET (final release), and a Debug build showed the that region of memory 
being overwritten by an 0xFE 0xEE pattern.

My kludge of a patch (attached) figures out the entry's index position within 
the stack, and resets the pointer after the m_stack.push_back() call. Someone 
with a better a full knowledge of the design of this class will want to make 
something more elegant and check the fix in.