Ceras icon indicating copy to clipboard operation
Ceras copied to clipboard

How to serialize DataSets / DataTables?

Open theRainbird opened this issue 4 years ago • 4 comments

Describe the bug

  • What are you trying to do? I try to serialize System.Data.DataSet types with Ceras.

  • What do you think should happen? They should be serialized to byte[] properly. May be I have to set some special config to allow DataSet seralization, but I don't know what to do. The FAQ says nothing about DataSets. I don't care if DataSets are rated bad or insecure by some people, because I have large applications with a big code base that I don't want to write from scratch.

  • What is actually happening? I'm getting a Ceras.Formatters.BannedTypeException: The type 'System.Data.DataSet' cannot be serialized, please mark the field/property that caused this Type to be included with the [Exclude] attribute or filter it out using the 'ShouldSerialize' callback. Specific reason for this type being banned: "This type can be exploited when deserializing malicious data". You should open an issue on GitHub or join the Discord server for support. at Ceras.Formatters.BannedTypes.ThrowIfBanned (System.Type type) [0x0017e] in :0 at Ceras.CerasSerializer.CreateMetaData (System.Type type, System.Boolean isStatic) [0x0001f] in :0 at Ceras.CerasSerializer.GetReferenceFormatter (System.Type type) [0x00000] in :0 at Ceras.CerasSerializer.Serialize[T] (T obj, System.Byte[]& buffer, System.Int32 offset) [0x00055] in :0 at Ceras.CerasSerializer.Serialize[T] (T obj) [0x00010] in :0 at CerasDataSetDemo.Program.Main (System.String[] args) [0x000f6] in :0

How to reproduce the bug Here is my example code to reproduce the issue:

        var dataSet = new DataSet("TestDataSet");
        var table = new DataTable("Person");
        var personIDColumn = table.Columns.Add("PersonID", typeof(int));
        personIDColumn.AutoIncrement = true;
        personIDColumn.AutoIncrementSeed = -1;
        personIDColumn.AutoIncrementStep = -1;
        table.Columns.Add("FirstName", typeof(string));
        table.Columns.Add("LastName", typeof(string));
        table.PrimaryKey = new DataColumn[] {personIDColumn};
        dataSet.Tables.Add(table);
        var row = table.NewRow();
        row["FirstName"] = "Max";
        row["LastName"] = "Mustermann";
        table.Rows.Add(row);
        row.AcceptChanges();
        row["FirstName"] = "Maxine";            
        var ceras = new CerasSerializer();            
        byte[] raw = ceras.Serialize(dataSet);
        var dataSet2 = ceras.Deserialize<DataSet>(raw);            
        Console.WriteLine(dataSet2.Tables["Person"].Rows[0].RowState);
        Console.WriteLine(dataSet2.Tables["Person"].Rows[0]["FirstName"]);
        Console.WriteLine(dataSet2.Tables["Person"].Rows[0]["FirstName", DataRowVersion.Original]);

Platform

  • I'm using Ceras for net4.7+

theRainbird avatar Feb 22 '20 18:02 theRainbird

I don't care if DataSets are rated bad or insecure by some people, because I have large applications with a big code base that I don't want to write from scratch.

Ok, whatever, I won't stand in your way 😝

You can compile the code yourself, comment out the corrosponding part here:

https://github.com/rikimaru0345/Ceras/blob/master/src/Ceras/Helpers/BannedTypes.cs#L74

But it is not a bug, the concern is valid. If you add a setting that enables one to turn off those bans, I'd merge it (assuming it is off by default).

rikimaru0345 avatar Feb 22 '20 22:02 rikimaru0345

Thank you so much.
This will help.

Sorry for tagging this issue as bug. You're right, DataSet serialization has security issues and so it should only be used in a trusted environment and never exposed to the Internet.

I'll try to extend settings with a "AllowDataSetSerialization" property, which is set false by default.

theRainbird avatar Feb 23 '20 15:02 theRainbird

I am going to second this request. I actually have a large number of applications that make use of large datatables and being able to cache these in something like redis would really help. I tried to muck with the BannedTypes but ran already into issues serializing CultureInfo. So an effort on DataTable would really be appreciated.

andreasmaier-abt avatar Apr 24 '20 15:04 andreasmaier-abt

@andreasmaier-abt Alright, noted. I'll add it to my todo list. But but it's probably going to take a while before I can make time to work on Ceras again (sorry ☹️).

  • [ ] Add a way to disable specific type-bans

but ran already into issues serializing CultureInfo.

What exactly is the problem with CultureInfo? I never really worked with it, but after looking at: https://docs.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.-ctor?view=netframework-4.8#System_Globalization_CultureInfo__ctor_System_Int32_ it seems like its basically just an int.

But if someone creates their own CultureInfo (based on some existing one and then just changing some properties), it's a little bit more complicated to serialize.

Anyway, whatever the issue with it is, adding support for it in Ceras is most likely very easy.

rikimaru0345 avatar Apr 24 '20 18:04 rikimaru0345