Visitar URL original
Incorrect DateTime Deserialization in Unity (2021.3.16f1) Mono .NET Standard 2.1 · Issue #1546 · MessagePack-CSharp/MessagePack-CSharp · GitHub
Skip to content

Incorrect DateTime Deserialization in Unity (2021.3.16f1) Mono .NET Standard 2.1 #1546

Closed

Description

@ImanNavidi

Bug description

When serialize and then deserialize a DateTime objects, sometimes the deserilized version would have a fixed value of "02/07/2106 06:28:15"!

Repro steps

using System;
using MessagePack;
using UnityEngine;
public class MainMenu : MonoBehaviour
{
  void Start()
  {
    for (int i = 0; i < 10; i++)
    {
      var b = MessagePackSerializer.Serialize(DateTime.Now);
      DateTime c = MessagePackSerializer.Deserialize<DateTime>(b);
      Debug.Log(c);
    }
  }
}

above script attached to maincamera of a 2d Scene.

Expected behavior

Deserialized value should be equal to DateTime value before serialization.

Actual behavior

Deserilized value would be DateTime object with value "02/07/2106 06:28:15"

  • Version used: 2.4.35
  • Runtime: Unity version 2021.3.16f1, Mono .NET Standard 2.1

Additional context

Activity

  1. changed the title [-]Incorrect DateTime Serialization in Unity (2021.3.16f1) Mono .NET Standard 2.1[/-] [+]Incorrect DateTime Deserialization in Unity (2021.3.16f1) Mono .NET Standard 2.1[/+] on Jan 1, 2023
  2. ImanNavidi commented on Jan 1, 2023

    @ImanNavidi
    ContributorAuthor

    I found that the problem is with deserialization and for specific times..
    Still investigating

  3. ImanNavidi commented on Jan 2, 2023

    @ImanNavidi
    ContributorAuthor

    Following code is causing problem on my system (hopefully!).
    https://github.com/neuecc/MessagePack-CSharp/blob/fa0da944a581cf9de241148dc5639d7959886326/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/SafeBitConverter.cs#L16

    long i1 = value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
    long i2 = value[4] | (value[5] << 8) | (value[6] << 16) | (value[7] << 24);
    
    

    bitwise operations between byte objects, turned the signed bits and caused the problem.

    changing the code to the following solved the problem for me:

    long i1 = value[0] * 1L + value[1] * 256L + value[2] * 65536L + value[3] * 16777216L;
    long i2 = value[4] * 1L + value[5] * 256L + value[6] * 65536L + value[7] * 16777216L;
    
    

    am I doing it right?

  4. AArnott commented on Jan 3, 2023

    @AArnott
    Collaborator

    Are you sure you're comparing apples to apples here? Your DateTime.Now value will be encoded in UTC time by msgpack (assuming you're using the default resolver), so when it is deserialized it comes out as UTC time, even though the original value was using Local time. Can you try the experiment with UtcNow instead?

  5. ImanNavidi commented on Jan 4, 2023

    @ImanNavidi
    ContributorAuthor

    Are you sure you're comparing apples to apples here? Your DateTime.Now value will be encoded in UTC time by msgpack (assuming you're using the default resolver), so when it is deserialized it comes out as UTC time, even though the original value was using Local time. Can you try the experiment with UtcNow instead?

    I was aware of UTC conversion.
    the problem was with the code provided.
    simply

    byte a = 255;
    long x = a << 24;    //Output = 0xFFFFFFFFFF000000 
    long y = a * 16777216L; //Output = 0x00000000FF000000 
    

    would not work as expected for a values greater than 127 (because of sign bits)

  6. ImanNavidi commented on Jan 5, 2023

    @ImanNavidi
    ContributorAuthor

    I have solved the problem with the multiplication version (code provided above) for myself.
    Not sure about the efficiency. If it is efficient, I can create a pull request

  7. AArnott commented on Jan 6, 2023

    @AArnott
    Collaborator

    I can't reproduce the problem here. Can you pick a value that fails?

    Or is this a bug in the mono runtime uniquely?

  8. ImanNavidi commented on Jan 6, 2023

    @ImanNavidi
    ContributorAuthor

    I can't reproduce the problem here. Can you pick a value that fails?

    Or is this a bug in the mono runtime uniquely?

    long.MaxValue or even 1000000000000.

  9. added a commit that references this issue on Jan 6, 2023
    e14cc10
  10. cubed-it commented on Feb 17, 2023

    @cubed-it

    How about a new unitypackage? This is a really nasty issue where you may not immediately recognize the origin. I just stumbled across the issue and it took me an hour to finally get here. I have now copied the changes by hand.

  11. AArnott commented on Mar 11, 2023

    @AArnott
    Collaborator

    @cubed-it, I guess watch #1562

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions