@@ -901,7 +901,7 @@ public Int32Collection ReadInt32Array(string fieldName)
901901
902902 for ( int ii = 0 ; ii < length ; ii ++ )
903903 {
904- values . Add ( ReadInt32 ( null ) ) ;
904+ values . Add ( SafeReadInt32 ( ) ) ;
905905 }
906906
907907 return values ;
@@ -945,7 +945,7 @@ public Int64Collection ReadInt64Array(string fieldName)
945945
946946 for ( int ii = 0 ; ii < length ; ii ++ )
947947 {
948- values . Add ( ReadInt64 ( null ) ) ;
948+ values . Add ( SafeReadInt64 ( ) ) ;
949949 }
950950
951951 return values ;
@@ -967,7 +967,7 @@ public UInt64Collection ReadUInt64Array(string fieldName)
967967
968968 for ( int ii = 0 ; ii < length ; ii ++ )
969969 {
970- values . Add ( ReadUInt64 ( null ) ) ;
970+ values . Add ( SafeReadUInt64 ( ) ) ;
971971 }
972972
973973 return values ;
@@ -989,7 +989,7 @@ public FloatCollection ReadFloatArray(string fieldName)
989989
990990 for ( int ii = 0 ; ii < length ; ii ++ )
991991 {
992- values . Add ( ReadFloat ( null ) ) ;
992+ values . Add ( SafeReadFloat ( ) ) ;
993993 }
994994
995995 return values ;
@@ -1011,7 +1011,7 @@ public DoubleCollection ReadDoubleArray(string fieldName)
10111011
10121012 for ( int ii = 0 ; ii < length ; ii ++ )
10131013 {
1014- values . Add ( ReadDouble ( null ) ) ;
1014+ values . Add ( SafeReadDouble ( ) ) ;
10151015 }
10161016
10171017 return values ;
@@ -1547,22 +1547,22 @@ private DiagnosticInfo ReadDiagnosticInfo(string fieldName, int depth)
15471547 // read the fields of the diagnostic info structure.
15481548 if ( ( encodingByte & ( byte ) DiagnosticInfoEncodingBits . SymbolicId ) != 0 )
15491549 {
1550- value . SymbolicId = ReadInt32 ( null ) ;
1550+ value . SymbolicId = SafeReadInt32 ( ) ;
15511551 }
15521552
15531553 if ( ( encodingByte & ( byte ) DiagnosticInfoEncodingBits . NamespaceUri ) != 0 )
15541554 {
1555- value . NamespaceUri = ReadInt32 ( null ) ;
1555+ value . NamespaceUri = SafeReadInt32 ( ) ;
15561556 }
15571557
15581558 if ( ( encodingByte & ( byte ) DiagnosticInfoEncodingBits . Locale ) != 0 )
15591559 {
1560- value . Locale = ReadInt32 ( null ) ;
1560+ value . Locale = SafeReadInt32 ( ) ;
15611561 }
15621562
15631563 if ( ( encodingByte & ( byte ) DiagnosticInfoEncodingBits . LocalizedText ) != 0 )
15641564 {
1565- value . LocalizedText = ReadInt32 ( null ) ;
1565+ value . LocalizedText = SafeReadInt32 ( ) ;
15661566 }
15671567
15681568 if ( ( encodingByte & ( byte ) DiagnosticInfoEncodingBits . AdditionalInfo ) != 0 )
@@ -1617,7 +1617,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
16171617
16181618 for ( int ii = 0 ; ii < values . Length ; ii ++ )
16191619 {
1620- values [ ii ] = ReadBoolean ( null ) ;
1620+ values [ ii ] = SafeReadBoolean ( ) ;
16211621 }
16221622
16231623 array = values ;
@@ -1656,7 +1656,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
16561656
16571657 for ( int ii = 0 ; ii < values . Length ; ii ++ )
16581658 {
1659- values [ ii ] = ReadInt16 ( null ) ;
1659+ values [ ii ] = SafeReadInt16 ( ) ;
16601660 }
16611661
16621662 array = values ;
@@ -1669,7 +1669,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
16691669
16701670 for ( int ii = 0 ; ii < values . Length ; ii ++ )
16711671 {
1672- values [ ii ] = ReadUInt16 ( null ) ;
1672+ values [ ii ] = SafeReadUInt16 ( ) ;
16731673 }
16741674
16751675 array = values ;
@@ -1683,7 +1683,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
16831683
16841684 for ( int ii = 0 ; ii < values . Length ; ii ++ )
16851685 {
1686- values [ ii ] = ReadInt32 ( null ) ;
1686+ values [ ii ] = SafeReadInt32 ( ) ;
16871687 }
16881688 array = values ;
16891689 break ;
@@ -1708,7 +1708,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
17081708
17091709 for ( int ii = 0 ; ii < values . Length ; ii ++ )
17101710 {
1711- values [ ii ] = ReadInt64 ( null ) ;
1711+ values [ ii ] = SafeReadInt64 ( ) ;
17121712 }
17131713
17141714 array = values ;
@@ -1721,7 +1721,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
17211721
17221722 for ( int ii = 0 ; ii < values . Length ; ii ++ )
17231723 {
1724- values [ ii ] = ReadUInt64 ( null ) ;
1724+ values [ ii ] = SafeReadUInt64 ( ) ;
17251725 }
17261726
17271727 array = values ;
@@ -1734,7 +1734,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
17341734
17351735 for ( int ii = 0 ; ii < values . Length ; ii ++ )
17361736 {
1737- values [ ii ] = ReadFloat ( null ) ;
1737+ values [ ii ] = SafeReadFloat ( ) ;
17381738 }
17391739
17401740 array = values ;
@@ -1747,7 +1747,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)
17471747
17481748 for ( int ii = 0 ; ii < values . Length ; ii ++ )
17491749 {
1750- values [ ii ] = ReadDouble ( null ) ;
1750+ values [ ii ] = SafeReadDouble ( ) ;
17511751 }
17521752
17531753 array = values ;
@@ -2096,15 +2096,16 @@ private ExtensionObject ReadExtensionObject()
20962096 return extension ;
20972097 }
20982098
2099- // get the length.
2100- int length = ReadInt32 ( null ) ;
2099+ // Get the length.
2100+ // Allow a length of -1 to support legacy devices that don't fill the length correctly
2101+ int length = SafeReadInt32 ( ) ;
21012102
21022103 // save the current position.
21032104 int start = Position ;
21042105
21052106 // create instance of type.
21062107 IEncodeable encodeable = null ;
2107- if ( systemType != null && length >= 0 )
2108+ if ( systemType != null && length >= - 1 )
21082109 {
21092110 encodeable = Activator . CreateInstance ( systemType ) as IEncodeable ;
21102111
@@ -2132,7 +2133,7 @@ private ExtensionObject ReadExtensionObject()
21322133
21332134 // verify the decoder did not exceed the length of the encodeable object
21342135 int used = Position - start ;
2135- if ( length != used )
2136+ if ( length >= 0 && length != used )
21362137 {
21372138 errorMessage = "Length mismatch" ;
21382139 exception = null ;
@@ -2211,11 +2212,14 @@ private ExtensionObject ReadExtensionObject()
22112212 }
22122213
22132214 // any unread data indicates a decoding error.
2214- long unused = length - ( Position - start ) ;
2215- if ( unused > 0 )
2215+ if ( length >= 0 )
22162216 {
2217- throw ServiceResultException . Create ( StatusCodes . BadDecodingError ,
2218- "Cannot skip {0} bytes of unknown extension object body with type '{1}'." , unused , extension . TypeId ) ;
2217+ long unused = length - ( Position - start ) ;
2218+ if ( unused > 0 )
2219+ {
2220+ throw ServiceResultException . Create ( StatusCodes . BadDecodingError ,
2221+ "Cannot skip {0} bytes of unknown extension object body with type '{1}'." , unused , extension . TypeId ) ;
2222+ }
22192223 }
22202224
22212225 if ( encodeable != null )
@@ -2307,7 +2311,7 @@ private Variant ReadVariantValue(string fieldName)
23072311
23082312 case BuiltInType . Boolean :
23092313 {
2310- value . Set ( ReadBoolean ( null ) ) ;
2314+ value . Set ( SafeReadBoolean ( ) ) ;
23112315 break ;
23122316 }
23132317
@@ -2325,20 +2329,20 @@ private Variant ReadVariantValue(string fieldName)
23252329
23262330 case BuiltInType . Int16 :
23272331 {
2328- value . Set ( ReadInt16 ( null ) ) ;
2332+ value . Set ( SafeReadInt16 ( ) ) ;
23292333 break ;
23302334 }
23312335
23322336 case BuiltInType . UInt16 :
23332337 {
2334- value . Set ( ReadUInt16 ( null ) ) ;
2338+ value . Set ( SafeReadUInt16 ( ) ) ;
23352339 break ;
23362340 }
23372341
23382342 case BuiltInType . Int32 :
23392343 case BuiltInType . Enumeration :
23402344 {
2341- value . Set ( ReadInt32 ( null ) ) ;
2345+ value . Set ( SafeReadInt32 ( ) ) ;
23422346 break ;
23432347 }
23442348
@@ -2350,25 +2354,25 @@ private Variant ReadVariantValue(string fieldName)
23502354
23512355 case BuiltInType . Int64 :
23522356 {
2353- value . Set ( ReadInt64 ( null ) ) ;
2357+ value . Set ( SafeReadInt64 ( ) ) ;
23542358 break ;
23552359 }
23562360
23572361 case BuiltInType . UInt64 :
23582362 {
2359- value . Set ( ReadUInt64 ( null ) ) ;
2363+ value . Set ( SafeReadUInt64 ( ) ) ;
23602364 break ;
23612365 }
23622366
23632367 case BuiltInType . Float :
23642368 {
2365- value . Set ( ReadFloat ( null ) ) ;
2369+ value . Set ( SafeReadFloat ( ) ) ;
23662370 break ;
23672371 }
23682372
23692373 case BuiltInType . Double :
23702374 {
2371- value . Set ( ReadDouble ( null ) ) ;
2375+ value . Set ( SafeReadDouble ( ) ) ;
23722376 break ;
23732377 }
23742378
0 commit comments