2010-12-08 33 views
5

Hemos creado una prueba de unidad que utiliza los métodos siguientes para generar al azar de texto UTF-8:C# XmlWriter y UTF8 no válido caracteres

 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(); 
      } 
     } 

En el envío de las cadenas UTF8 al azar a nuestra lógica de negocio, XmlWriter escribe la cadena generada y puede con el error:

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) 

queremos apoyar cualquier cadena puede ser aprobada en, y necesitan estos caracteres no válidos escaparon de alguna manera.

XmlWriter ya se escapa de cosas como &, <,>, etc., ¿cómo podemos tratar con otros caracteres no válidos como los caracteres de control, etc.?

PS - quiero saber si es defectuoso nuestra generador UTF8 (ya estoy viendo donde no debería dejar que genere '\ 0')

Respuesta

7

El XmlConvert Class tiene muchos métodos útiles (como EncodeName, IsXmlChar, ...) para asegurarse de que está compilando Xml válido.

+0

Creo que podría verificar IsXmlChar en mi generador de bytes aleatorios y volver a intentarlo si falla. Creo que esta es una buena solución. No nos preocupa demasiado el rendimiento, ya que se trata de pruebas unitarias. – jonathanpeppers

+0

Al usar caracteres aleatorios con un conjunto de pruebas, puede dificultar la recreación de una prueba fallida, ya que sus pruebas no son deterministas. – lavinio

+0

Es por eso que revisamos la salida de depuración de las pruebas fallidas. Nuestro resultado de depuración es muy extenso. Simplemente tomamos la entrada fallida y hacemos una prueba específica para esa entrada. – jonathanpeppers

6

Su generador UTF8 parece ser defectuoso. Hay muchas secuencias de bytes que son codificaciones UTF-8 no válidas.

Una mejor manera de generar válidos azar UTF-8 codificaciones es generar caracteres aleatorios, ponerlos en una cadena y luego codificar la cadena en UTF-8.

+3

¿Tienes un ejemplo de código? – jonathanpeppers

2

Mark señala que no todas las secuencias de bytes son una secuencia UTF-8 válida.

Me gustaría agregar que no todos los caracteres pueden existir en un documento XML. Solo some characters are valid, y esto es cierto incluso si están codificados como numeric character reference.

Actualización: Si desea codificar datos binarios arbitrarios en XML, utilice Base64 u otra codificación antes de escribirlos en XML.

5

hay dos problemas:

  1. No todos los caracteres son válidos para XML, incluso escaparon. Para XML 1.0, los únicos caracteres con un valor de punto de código Unicode de menos de 0x0020 que son válidos son TAB (&#9;), LF (&#10;) y CR (&#13;). Ver XML 1.0, Section 2.2, Characters.

    Para XML 1.1, que es relativamente poco compatible con los sistemas, cualquier carácter excepto NUL se puede escapar de esta manera.

  2. No todas las secuencias de bytes son válidas para UTF-8. Por ejemplo, según el specification, "Los valores de octeto C0, C1, F5 a FF nunca aparecen". Probablemente sea mejor que solo cree String s de caracteres e ignore UTF-8, o cree el String, convirtiéndolo a UTF-8 y viceversa si realmente le interesa la codificación.