UnparsedResultIQ does not contain full content

Hi all,

I have an issue with Smack 4.0.2 when receiving IQ stanzas. I didn’t create a provider because I need the raw unparsed stanza but
my IQ element’s 1st child is always missing. I traced it down to:

/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java, lines 642-646:

// Only handle unknown IQs of type result. Types of ‘get’ and ‘set’ which are not understood
// have to be answered with an IQ error response. See the code a few lines below
else if (IQ.Type.result == type){
// No Provider found for the IQ stanza, parse it to an UnparsedIQ instance
// so that the content of the IQ can be examined later on
iqPacket = new UnparsedResultIQ(parseContent(parser));
}

The issue is that parseContent() is used and this skips the IQ element’s first
child. I beleive this is an error because the spec says the the IQ element may
have one direct child, which is what I have. It has a custom namespace. I think
the result of parsing an unknown IQ result type should yeild the original msg.
To illustrate, I send something like this from the server:

and Smack gives my processPacket() method:

which is not what I sent…

If instead you did this:

// Only handle unknown IQs of type result. Types of ‘get’ and ‘set’ which are not understood

// have to be answered with an IQ error response. See the code a few lines below

else if (IQ.Type.result == type){

// No Provider found for the IQ stanza, parse it to an UnparsedIQ instance

// so that the content of the IQ can be examined later on

iqPacket = new UnparsedResultIQ(parseContentDepth(parser, parser.getDepth()));

}

it would work as expected, the whole unparsed IQ stanza, as received, would be handed over to the processPacket() method.

I didn’t create a provider because I need the raw unparsed stanza but

my IQ element’s 1st child is always missing.

Simply create a IQ class and provider that parses your the outer ‘mynode’ element and stores the values into fields. Then use parseContent() to parse the content of ‘mynode’ and create a toXML method that reassembles the stanza.

Simply create a IQ class and provider that parses your the outer ‘mynode’ element and stores the values into fields. Then use parseContent() to parse the content of ‘mynode’ and create a toXML method that reassembles the stanza.

This is a workaround, an valid unknown IQ node with no provider should be handed back unparsed and unmodified, this is currently not the case, it is unparsed but modified.

I don’t consider this to be an workaround, this is the only valid and sound approach.

You are welcome to provide patches that change Smack in the way you want. But in this case, you may find that it’s not so trivial to restore the inner IQ element name and it’s attributes, so that they end up in a UnparsedResultIQ.

You are welcome to provide patches that change Smack in the way you want. But in this case, you may find that it’s not so trivial to restore the inner IQ element name and it’s attributes, so that they end up in a UnparsedResultIQ.

It was quite Trivial actually, just look at how it was done in my original msg, I posted the solution there (you may have not noticed since I posted this at the same moment that you replied).

Ahh right, sorry I got confused. I thought the parser position would have been already behind the ‘mynode’ element. Change applied with minor modifications as Include the full content in UnparsedResultIQ · 80f6252 · igniterealtime/Smack · GitHub

I believe that this was actually the case when I once implemented the UnparsedResultIQ feature. But changes to parseContent and parseElement may have introduced the bug. Thanks for reporting.

But still, you should really create an IQ class and register a provider for it. UnparsedResultIQ exists mostly for debugging purposes.

Thanks Flow.

I agree in principal, but in my case I use another XMPP server and I implemented one set of XMPP marshgallers/unmarshallers that are used both by the client and the server (so I don’t have to implement this twice), this is why I really just need the raw XML as a string.

Thanks for the good work on Smack!