سؤال

مرحبًا يا شباب ، لدي تطبيق يحفظ البيانات باستخدام XML. لقد تلقيت مؤخرًا تقريراً خطأ من مستخدم غير قادر على فتح ملف بياناتها. يبدو أن المحلل فشل عندما واجه شخصية سيئة.

لحسن الحظ ، لدي نسخة من ملف البيانات الخاص بها ، لذلك تمكنت من العثور على الجاني ، لكنني لا أفهم ما هو عليه ، أو كيف وصلت إلى هناك. (لأن هذا هو كل إدخال لوحة المفاتيح من المستخدم.) الأحرف المخالفة هي:

attributeName="Some text then XXX"

حيث "xxx" ، وفقًا لمحرر Hex:

0A 0A 00

0A هو خلاصة خط بقدر ما أستطيع أن أقول ، ولكن كيف تنتهي الشخصية الفارغة إلى هناك؟! هذا هو أول خطأ رأيته من هذه الطبيعة.

هل كانت مفيدة؟

المحلول

أعتقد أن المشكلة التي تراها معروفة قليلاً ، ولكنها عيب خطير للغاية في XML. باختصار: لا يمكن أن تحتوي قيم XML على شخصيات معينة ، وليس فقط لا يمكن أن تكون في نص XML ، ولكن لا يمكن الهروب منها حتى باستخدام &#dddd ؛ الرموز.

يمكن العثور على XML Charset هنا: http://www.w3.org/tr/rec-xml/#charsets, ، وهو: #x9 | #xa | #xd | [#x20-#xd7ff] | [#xe000-#xfffd] | [#x10000-#x10ffff].

هذا يعني أنه إذا لم يكن لسلسلة أي حرف غير مدرج في هذا Charset ، فلا يمكن تسلسلها في قيمة XML. الطريقة الوحيدة لتخزين هذه السلسلة هي تسلسلها إلى قاعدة 64 كبيانات ثنائية.

العديد من الأطر الشائعة ، بما في ذلك MSXML و .NET ستسمح بوضع البيانات السيئة في قيم XML ، ومن ثم سترفض تخلص من مثل هذه XML. إليك مثال ، لقطة شاشة: http://vvcap.net/db/db94w-13uwcknxsztito.htp, ورمز المصدر:

using System;
using System.Xml.Serialization;
using System.Xml;

[Serializable] public class TestClass
{
    [XmlAttribute]
    public string Member { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var ser = new XmlSerializer(typeof(TestClass));
        var tc = new TestClass() { Member = "zzz \x19 zzz" };
        var stream = new System.IO.StringWriter();
        ser.Serialize(stream, tc);
        var xml = stream.ToString();
        var stream2 = new System.IO.StringReader(stream.ToString());
        var tc2 = ser.Deserialize(stream2);
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top