You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@axis.apache.org by "Tim Bartley (JIRA)" <ax...@ws.apache.org> on 2005/03/08 02:18:52 UTC

[jira] Commented: (AXISCPP-511) Deserialization of complex nested arrays broken

     [ http://issues.apache.org/jira/browse/AXISCPP-511?page=comments#action_60398 ]
     
Tim Bartley commented on AXISCPP-511:
-------------------------------------

This appears to be a bug in the stub code generated for deserializing arrays. Stepping
through the deserialization the generic deserialization code correctly accesses all of
the data but when the generated code converts the Object[] array returned by the
generic code to an Object*[] array returned to the stub's caller things go awry.

Consider the stub deserialization code generated for AttributeList of the attached
WSDL:

int Axis_DeSerialize_AttributeList(AttributeList* param, IWrapperSoapDeSerializer* pIWSDZ)
{
	Axis_Array array;

	array = pIWSDZ->getCmplxArray((void*)Axis_DeSerialize_Attribute,
								  (void*)Axis_Create_Attribute,
								  (void*)Axis_Delete_Attribute,
								  (void*)Axis_GetSize_Attribute,
								  "attributes", Axis_URI_Attribute);

	// Additional code to find is reference is pointer or pointer to a pointer
	Attribute **	pp0 = param->attributes.m_Array;

	param->attributes.m_Size = array.m_Size;

	if( param->attributes.m_Array == NULL)
	{
		pp0 = new Attribute*[array.m_Size];
		param->attributes.m_Array = pp0;
	}

	Attribute *	p0 = (Attribute *) array.m_Array;

	for( int iCount0 = 0; iCount0 < array.m_Size; iCount0++)
	{
		pp0[iCount0] = new Attribute();
		*(pp0[iCount0]) = p0[iCount0];
	}
	delete [] p0;
	// End
	return pIWSDZ->getStatus();
}

The array returned by getCmplxArray looks fine but in the last loop of the code
when pp0 is being set up the assignment:

     *(pp0[iCount0]) = p0[iCount0]

does not perform a deep copy so when

    delete [] p0

is invoked to clean up p0 the array elements destructors fire and cleanup the inner array
and the members of pp0 now reference deallocated memory. The next memory allocation reuses this referenced memory and the data gets corrupted.

In my opinion, this assignment to a new object is unnecessary (particularly from a performance point of view - memory allocations are just about the slowest (non-IO) thing you can do and particularly slows down multi-threaded applications but I'll save this rant for another discussion) and the set up of pp0 could simply be generated as:


	for( int iCount0 = 0; iCount0 < array.m_Size; iCount0++)
	{
		pp0[iCount0] = &p0[iCount0];
	}

without p0 being deleted after this loop. Callers would then need to know to "delete [] *param->attribute.m_Array" as well as "delete [] param->attribute.m_Array" - or better still the
generated AttributeList destructor should do this.

When I modify the stub by hand as above I see the correctly deserialized data.

Alternatively, and perhaps better still, the array references generated could simply be

typedef struct Attribute_ArrayTag {
       Attribute* m_Array;
       int m_Size;
} AttributeArray

instead of having the double indirection

typedef struct Attribute_ArrayTag {
       Attribute** m_Array;
       int m_Size;
} AttributeArray

This would remove the need to perform the pointer array allocation and set up at all and the existing generated destructor would be correct.

> Deserialization of complex nested arrays broken
> -----------------------------------------------
>
>          Key: AXISCPP-511
>          URL: http://issues.apache.org/jira/browse/AXISCPP-511
>      Project: Axis-C++
>         Type: Bug
>   Components: Deserialization
>     Versions: current (nightly)
>  Environment: cvs, Mar 7, 2005
>     Reporter: Tim Bartley
>  Attachments: Service2.wsdl, axis.trace
>
> Deserialization of nested complex arrays seems very broken.
> With the attached wsdl and SOAP transaction I see the Response structure filled in as follows:
> result: 1
> outAttrs.m_Array: 0x8080928
> outAttrs.m_Size:  2
> outAttrs.m_Array[0]: 0x8080968
> outAttrs.m_Array[1]: 0x8080a80
> outAttrs.m_Array[0]:
>     attributes.m_Array: 0x80808a8
>     attributes.m_Size:  2
>     attributes.m_Array[0]: 0x1
>     attributes.m_Array[1]: (nil)
>     attributes.m_Array: 0x8080998
> outAttrs.m_Array[1]:
>     attributes.m_Size:  3
>     attributes.m_Array[0]: 0x1
>     attributes.m_Array[1]: 0x80809b8
>     attributes.m_Array[2]: 0x80809c8
> As you can see the outer array looks OK but the inner arrays are garbage. The  values of outAttrs.m_Array[x]->attributes.m_Array[y] should be valid pointers to Attributes but theri values are clearly not valid pointers.
> Regards,
> Tim

-- 
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
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira