rpgmaker / NetJSON

Faster than Any Binary? Benchmark: http://theburningmonk.com/2014/08/json-serializers-benchmarks-updated-2/
MIT License
225 stars 29 forks source link

ulong enum #219

Closed cubed-it closed 5 years ago

cubed-it commented 5 years ago

Hey there,

I have found two issues:

  1. FlagEnumToString is throwing an InvalidCastException if you have a enum value that is larger than an int32.
  2. This one is tricky and I unfortunatelly cannot reproduce it. We have changed a enum from uint to ulong and when deserializing we get the following exception:
    Ein Ausnahmefehler des Typs "System.AccessViolationException" ist in NetJSON.dll aufgetreten.
    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

    It happens when CreateSerializer() is called on the last Emit call. (Maybe this is nocht the actual line, because it was a dotpeak decompiled assembly and this is sometime not exactly at the right line, could be one more maybe). However, there is not any more information I get or can provide. Maybe you have any idea or hint what could cause this or how to make a further diagnosis?

Thank!

rpgmaker commented 5 years ago

Thanks for the details. I can look into the code to see what causes it. Thanks

rpgmaker commented 5 years ago

Could you give an example of what you are trying to do? I could not reproduce it. Is the issue trying to deserialize ulong value into an int?

image

rpgmaker commented 5 years ago

When i tried type mismatch. I only got a stackoverflow exception instead of the access violation exception. So based on my test so far, an example to reproduce will be really useful. Thanks

image

cubed-it commented 5 years ago

My fault, I forgot to mention that it is a Flag-Enum. Sorry :(


   [Flags]
   public enum ULongEnum : ulong
   {
      ULongEnumValueA = 0x00400,
      ULongEnumValueB = 0x400000000
   }

   public class ULongClass
   {
      public ULongEnum LongEnum { get; set; }
   }

         var obj = new ULongClass() {LongEnum = ULongEnum.ULongEnumValueA | ULongEnum.ULongEnumValueB};
         var json = NetJSON.NetJSON.Serialize(obj);
         var dto = NetJSON.NetJSON.Deserialize<ULongClass>(json);

So that will result in issue 1, but unfortunately not in mystic issue 2...

rpgmaker commented 5 years ago

I see. Thanks for the details

cubed-it commented 5 years ago

Regarding my second problem, I was now able to reproduce the problem. It occurs when a long or ulong enum is used. However, exclusively out of a uwp project. Your example code within a UWP project then generates the following message. Unfortunately there is almost no further info. Looks like a bug in the platform. :(

longex

rpgmaker commented 5 years ago

The problem is in the flagenumToStr method that try to cast to int and check for zero as an optimization. If you remove that then it works fine. But I found a weird bug when in release mode that give junk data when a single value is used as the enum from the flag. Trying to figure out the cause of it.

cubed-it commented 5 years ago

One question not related to my problem: If I serialize an interface type, why are properties of the base interface ignored?

rpgmaker commented 5 years ago

Can I see an example of what you are trying to do?

Thanks

cubed-it commented 5 years ago

Sure: image


   public class SimpleClass : ISimpleClass
   {
      public string SimpleClassProp { get; set; }
      public string SimpleClassBaseProp { get; set; }
   }

   public interface ISimpleClass : ISimpleClassBase
   {
      string SimpleClassProp { get; set; }
   }
   public interface ISimpleClassBase
   {
      string SimpleClassBaseProp { get; set; }
   }

var jsonSettingsB = new NetJSON.NetJSONSettings() { DateFormat = NetJSON.NetJSONDateFormat.ISO, SkipDefaultValue = false, UseEnumString = true, };
            var sc = new SimpleClass();
            var isc = (ISimpleClass) sc;
            var scs = NetJSON.NetJSON.Serialize(typeof(SimpleClass), sc, jsonSettingsB);
            var iscs = NetJSON.NetJSON.Serialize(typeof(ISimpleClass), isc, jsonSettingsB);
rpgmaker commented 5 years ago

So the interface will not get the other properties since it does not exists. It only exists in the class itself. You need to enable NetJson.IncludeTypeInformation = true and try again

rpgmaker commented 5 years ago

Please verify if the changes i did solves your problem by using the code from the branch. If so, i can create a nuget package for it. In regards to the enumeration ulong.

Please a separate ticket to discuss the serialization of Interface

Thanks,

cubed-it commented 5 years ago

The first problem FlagEnumToString is solved, thanks! :) However the serialization issue has only been noticed by coincidence. My main issue is still present, the deserialization of long enum in uwp as described here: https://github.com/rpgmaker/NetJSON/issues/219#issuecomment-495093598 (As I also said before, it looks like a platform error to me. it doesn't have a big priority for me either, since we can workaround without using a long enum for the time being. nevertheless, it remains an unintentional misbehaviour...)