2010-12-08 23 views
5

Wir einen Komponententest erstellt, die die folgenden Methoden verwendet Zufalls UTF8 Text zu generieren:C# XmlWriter und ungültige UTF8 Zeichen

 private static Random _rand = new Random(Environment.TickCount); 

     public static byte CreateByte() 
     { 
      return (byte)_rand.Next(byte.MinValue, byte.MaxValue + 1); 
     } 

     public static byte[] CreateByteArray(int length) 
     { 
      return Repeat(CreateByte, length).ToArray(); 
     } 

     public static string CreateUtf8String(int length) 
     { 
      return Encoding.UTF8.GetString(CreateByteArray(length)); 
     } 

     private static IEnumerable<T> Repeat<T>(Func<T> func, int count) 
     { 
      for (int i = 0; i < count; i++) 
      { 
       yield return func(); 
      } 
     } 

Beim Senden der Zufalls UTF8-Strings in unseren Business-Logik, schreibt XmlWriter die generierte Zeichenfolge und kann nicht mit dem Fehler:

Test method UnitTest.Utf8 threw exception: 
System.ArgumentException: ' ', hexadecimal value 0x0E, is an invalid character. 

System.Xml.XmlUtf8RawTextWriter.InvalidXmlChar(Int32 ch, Byte* pDst, Boolean entitize) 
System.Xml.XmlUtf8RawTextWriter.WriteAttributeTextBlock(Char* pSrc, Char* pSrcEnd) 
System.Xml.XmlUtf8RawTextWriter.WriteString(String text) 
System.Xml.XmlUtf8RawTextWriterIndent.WriteString(String text) 
System.Xml.XmlWellFormedWriter.WriteString(String text) 
System.Xml.XmlWriter.WriteAttributeString(String localName, String value) 

Wir wollen jede mögliche Zeichenfolge unterstützen übergeben werden, und müssen diese ungültigen Zeichen irgendwie entkommen.

XmlWriter entkommt bereits Dinge wie &, <,>, usw., wie können wir mit anderen ungültigen Zeichen wie Steuerzeichen usw. umgehen?

PS - lassen Sie mich wissen, wenn unser UTF8 Generator fehlerhaft ist (ich sehe schon, wo ich sollte es ‚\ 0‘ nicht zulassen, erzeugen) erscheint

Antwort

7

Die XmlConvert Class hat viele nützliche Methoden (wie EncodeName, IsXmlChar, ...) um sicherzustellen, dass Sie gültige Xml erstellen.

+0

Ich denke, ich könnte IsXmlChar auf meinem zufälligen Byte-Generator überprüfen und versuchen, wenn es fehlschlägt. Ich denke, das ist eine ziemlich gute Lösung. Wir machen uns keine allzu großen Sorgen um die Leistung, denn das ist Unit Testing. – jonathanpeppers

+0

Wenn Sie zufällige Zeichen mit einer Testsuite verwenden, kann es schwierig sein, einen fehlgeschlagenen Test neu zu erstellen, da Ihre Tests nicht deterministisch sind. – lavinio

+0

Deshalb überprüfen wir die Debug-Ausgabe von fehlgeschlagenen Tests. Unsere Debug-Ausgabe ist sehr umfangreich. Wir nehmen nur die fehlgeschlagene Eingabe und machen einen spezifischen Test für diese Eingabe. – jonathanpeppers

6

Ihr UTF8 Generator fehlerhaft werden. Es gibt viele Bytefolgen, die ungültige UTF-8-Kodierungen sind.

Eine bessere Möglichkeit zum Generieren gültig zufällige UTF-8-Kodierungen ist zufällige Zeichen zu generieren, setzen Sie sie in eine Zeichenfolge und kodieren Sie die Zeichenfolge dann in UTF-8.

+3

Haben Sie ein Codebeispiel? – jonathanpeppers

2

Markierung weist darauf hin, dass nicht jede Byte-Sequenz eine gültige UTF-8-Sequenz ist.

Ich möchte hinzufügen, dass nicht jedes Zeichen in einem XML-Dokument vorhanden sein kann. Nur some characters are valid, und dies gilt auch dann, wenn sie als numeric character reference codiert sind.

Aktualisierung: Wenn Sie beliebige Binärdaten in XML codieren möchten, verwenden Sie Base64 oder eine andere Codierung, bevor Sie sie in XML schreiben.

5

Es gibt zwei Probleme:

  1. Nicht alle Zeichen sind gültig für XML, entging auch. Für XML 1.0 sind die einzigen Zeichen mit einem gültigen Unicode-Codepunktwert von weniger als 0x0020 TAB (&#9;), LF (&#10;) und CR (&#13;). Siehe XML 1.0, Section 2.2, Characters.

    Für XML 1.1, das relativ wenige Systeme unterstützen, kann auf diese Weise jedes Zeichen außer NUL ausgeblendet werden.

  2. Nicht alle Bytefolgen sind für UTF-8 gültig. Zum Beispiel, nach der specification, "Die Oktett Werte C0, C1, F5 bis FF erscheinen nie." Wahrscheinlich wäre es besser, nur String s Zeichen zu erstellen und UTF-8 zu ignorieren oder das String zu erstellen, es in UTF-8 umzuwandeln und zurück, wenn Sie wirklich in Codierung sind.