Strani personaggi in file XML (dall'input dell'utente?)
-
25-09-2019 - |
Domanda
Ciao ragazzi, Ho un'applicazione che consente di salvare i dati utilizzando XML. Recentemente ho ricevuto una segnalazione di bug da un utente che è in grado di aprire il suo file di dati. Il parser Errore all'interno quando ha incontrato un cattivo carattere.
Per fortuna, ho una copia del suo file di dati, così mi è stato in grado di trovare il colpevole, ma non capisco di cosa si tratta, o come lì ottenuto. (Come questo è tutto l'input di tastiera dall'utente.) I caratteri problematici sono:
attributeName="Some text then XXX"
Se il "XXX" è, secondo un editor esadecimale:
0A 0A 00
Il 0A è un avanzamento riga, per quanto posso dire, ma come diavolo fosse un fine carattere null lassù ?! Questo è il primo bug che ho visto di questa natura.
Soluzione
Credo che il problema che si sta vedendo è un poco conosciuto, ma molto grave difetto in XML. In poche parole: i valori XML non possono contenere alcuni caratteri, e non solo loro, non possono essere in testo XML, ma non possono nemmeno essere sfuggito usando & # DDDD; notazione.
Valido charset XML potrebbe essere trovato qui: http://www.w3.org / TR / REC-xml / # charsets , ed è: # x9 | #xA | #xD | [# # X20- xD7FF] | [# # XE000- xFFFD] | [# # X10000- x10FFFF].
Ciò significa che se la stringa ha carattere non incluso nel questo set di caratteri, non può essere serializzato in valore XML. L'unico modo per conservare tale stringa è quello di serializzare a base64 come dati binari.
Molti quadri popolari, tra cui MSXML e .NET permetterebbe di mettere dati non validi nei valori XML, e poi si sarebbe rifiutato di deserializzare come XML. Ecco un esempio, screenshot: http://vvcap.net/db/Db94W-13uwCkNXSZTitO.htp, e il codice sorgente:
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);
}
}