Pergunta

Ei pessoal, eu tenho um aplicativo que salva dados usando XML. Recentemente, recebi um relatório de bug de um usuário que não consegue abrir seu arquivo de dados. O analisador aparentemente falhou quando encontrou um caráter ruim.

Felizmente, tenho uma cópia do arquivo de dados dela, por isso pude encontrar o culpado, mas não entendo o que é ou como chegou lá. (Como tudo isso é a entrada do teclado do usuário.) Os caracteres ofensivos são:

attributeName="Some text then XXX"

Onde está o "xxx", de acordo com um editor hexadecimal:

0A 0A 00

O 0A é um feed de linha, tanto quanto eu sei, mas como diabos um personagem nulo acabaria lá?! Este é o primeiro bug que eu já vi dessa natureza.

Foi útil?

Solução

Eu acho que o problema que você está vendo é um pouco conhecido, mas uma falha muito séria no XML. Em poucas palavras: os valores XML não podem conter certos caracteres, e não apenas eles não podem estar no texto XML, mas também não podem ser escapados usando &#dddd; notação.

O Charset XML válido pode ser encontrado aqui: http://www.w3.org/tr/rec-xml/#charsets, e é: #x9 | #xa | #xd | [#x20-#xd7ff] | [#xe000-#xfffd] | [#x10000-#x10ffff].

Isso significa que, se sua string tiver algum caractere não incluído neste charset, ela não poderá ser serializada no valor XML. A única maneira de armazenar essa string é serializar -a no Base64 como dados binários.

Muitas estruturas populares, incluindo MSXML e .NET, permitiriam colocar dados ruins nos valores XML e, em seguida, se recusariam a desserializar esse XML. Aqui está um exemplo, captura de tela: http://vvcap.net/db/db94w-13uwcknxsztito.htp, e código -fonte:

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);
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top