CPCCoder
Hi, ## Description In the current DMVC Framework version, valid `Int32` values may be classified by JsonDataObjects as `jdtLong` or `jdtULong`. The deserialization code for `NullableInt32` does not handle these JSON token types correctly. As a result, valid boundary values can be rejected, while values outside the `Int32` range must still be rejected. The previous DMVC version accepted the valid `Int32` boundary values. ## Reproduction ```delphi program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, MVCFramework.Nullables, MVCFramework.Serializer.Commons, MVCFramework.Serializer.JsonDataObjects; type TTestDTO = class public Value: NullableInt32; end; var DTO: TTestDTO; Serializer: TMVCJsonDataObjectsSerializer; begin try Writeln('DMVC NullableInt32 deserialization reproduction'); Writeln('JSON field: value'); Writeln('JSON value: 1147483647'); Writeln; DTO := TTestDTO.Create; Serializer := TMVCJsonDataObjectsSerializer.Create(nil); try Serializer.DeserializeObject( '{"value":1147483647}', DTO, stFields); Writeln('HasValue: ', BoolToStr(DTO.Value.HasValue, True)); if DTO.Value.HasValue then Writeln('Value: ', IntToStr(DTO.Value.Value)) else Writeln('Value: <null>'); if not DTO.Value.HasValue then Writeln('RESULT: FAIL - the value was deserialized as null.') else if DTO.Value.Value <> 1147483647 then Writeln('RESULT: FAIL - the deserialized value is incorrect.') else Writeln('RESULT: PASS - NullableInt32 was deserialized correctly.'); finally Serializer.Free; DTO.Free; end; except on E: Exception do begin Writeln('RESULT: EXCEPTION'); Writeln('Class: ', E.ClassName); Writeln('Message: ', E.Message); end; end; Writeln; Write('Press ENTER to exit...'); Readln; end. ``` ## Expected behavior | JSON value | Expected result | | --- | --- | | `2147483647` | Accepted | | `-2147483648` | Accepted | | `2147483648` | Rejected as Int32 overflow | | `-2147483649` | Rejected as Int32 overflow | ## Current behavior Depending on the JSON token classification, valid `Int32` values can result in an exception such as: ```text Cannot deserialize long integer value ``` The problem occurs because the `jdtLong`/`jdtULong` deserialization path handles `NullableInt64` and other types, but not `NullableInt32`. ## Suggested fix The `jdtLong` and `jdtULong` branches should explicitly support `NullableInt32` and perform a range check before converting the value: ```delphi if lValueTypeInfo = TypeInfo(NullableInt32) then begin case AJSONObject[APropertyName].Typ of jdtLong: begin if (AJSONObject[APropertyName].LongValue < Low(Int32)) or (AJSONObject[APropertyName].LongValue > High(Int32)) then raise EMVCDeserializationException.CreateFmt( 'Integer value out of range for "%s"', [APropertyName]); AValue := TValue.From<NullableInt32>( NullableInt32(AJSONObject[APropertyName].LongValue)); end; jdtULong: begin if AJSONObject[APropertyName].ULongValue > UInt64(High(Int32)) then raise EMVCDeserializationException.CreateFmt( 'Integer value out of range for "%s"', [APropertyName]); AValue := TValue.From<NullableInt32>( NullableInt32(AJSONObject[APropertyName].ULongValue)); end; else raise EMVCDeserializationException.CreateFmt( 'Cannot deserialize integer value for "%s"', [APropertyName]); end; end; ``` The same logic should also be applied to the corresponding record-field deserialization path. ## Additional information This is not specific to a custom nullable implementation. It can be reproduced with DMVC's own `NullableInt32` type. The issue appears to be related to the changed JSON numeric classification in the newer JsonDataObjects version. Either the parser should preserve the previous classification, or the DMVC deserializer should accept all compatible numeric token types and validate the target type's range. Thank you, Kosta