OPCFoundation / UA-Java-Legacy

This repository is provided by OPC Foundation as legacy support for an Java version for OPC UA.
https://github.com/OPCFoundation/UA-.NETStandard
Other
355 stars 227 forks source link

ExtensionObject.binaryEncode overrides the serializer of the given EncoderContext permanently #180

Closed bjakke closed 5 years ago

bjakke commented 5 years ago

Methods in ExtensionObject (with the encode calling binaryEncode or calls to binaryEncode directly):

public static ExtensionObject binaryEncode(Structure encodeable, IEncodeableSerializer serializer, EncoderContext ctx) throws EncodingException
public static ExtensionObject encode(Structure encodeable, QualifiedName encodingType, IEncodeableSerializer serializer, EncoderContext ctx) throws EncodingException

As part of the binaryEncode the serializer given as parameter is set to the context via ctx.setEncodeableSerializer(serializer). In practice this will override the current serializer that was part of the context. Also the versions of the (binary)Encode not taking serializers use the StackUtils.getDefaultSerializer(), which means a more special one could get overridden. Additionally if the given serializer does not delegate to the default one, a lots of standard types cannot be encoded anymore. If the given context is the default one that is used to decode messages that will break as well.

Therefore both methods should be deprecated (as in practice the serializer should already be in the context), and the ones that do not take the serializer should not use the StackUtils.getDefaultSerializer() but instead just pass the context to the BinaryEncoder which will then use the serializer of the context (which by default does have the default serializer usually). The deprecated method impls can be changed to defensively copy the given context to avoid breaking it.