8

ソケットを介して外部インターフェイスから受信した XML を読み込もうとしています。問題は、XML ヘッダーでエンコーディングが正しく指定されていないことです (iso-8859-1 と表示されていますが、utf-16BE です)。エンコーディングが utf-16BE であることが文書化されていますが、どうやら正しいエンコーディングを設定するのを忘れていたようです。

逆シリアル化するときにエンコーディングを無視するには、次のように StringReader を使用します。

    private static T DeserializeXmlData<T>(byte[] xmlData)
    {
        var xmlString = Encoding.BigEndianUnicode.GetString(xmlData);
        using (var reader = new StringReader(xmlString))
        {
            reader.ReadLine(); // Eat header line
            using (var xmlReader = XmlReader.Create(reader))
            {
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(xmlReader);
            }
        }
    }

上記は実際には問題なく動作しますが、ReadLine を呼び出してヘッダー行をスキップする部分が好きではありません。XML ヘッダーで指定されたエンコーディングをバイパスする脆弱性の低い方法はありますか?

StreamReader を使用したソリューション

StreamReader を使用することで、XML ヘッダーで指定されたエンコーディングをオーバーライドできます。XmlReaderSettings.IgnoreProcessingInstructions を指定してもしなくても、違いはありませんでした。興味深いことに、StreamReader は、Unicode のバイト順マークが見つかった場合、指定されたエンコーディングを無視します。

要点をまとめると:

  • XmlReader が TextReader で初期化されている場合、XML ヘッダーのエンコーディングは無視されます。
  • StringReader が使用されている場合、Unicode バイト順マークが存在すると、XmlReader は失敗します。
  • StreamReader が使用されている場合、Unicode バイト順マークが StreamReader エンコーディングをオーバーライドします。
  • XmlReaderSettings.IgnoreProcessingInstructions = true は、TextReader を使用する場合に違いはありません。

結論として、最も堅牢なソリューションは、StreamReader を使用することのようです。これは、存在する場合、バイト オーダー マークを使用するためです。

    private static T DeserializeXmlData<T>(byte[] xmlData)
    {
        using (var xmlDataStream = new MemoryStream(xmlData))
        {
            using (var reader = new StreamReader(xmlDataStream, Encoding.BigEndianUnicode))
            {
                using (var xmlReader = XmlReader.Create(reader))
                {
                    var serializer = new XmlSerializer(typeof (T));
                    return (T) serializer.Deserialize(xmlReader);
                }
            }
        }
    }
4

2 に答える 2

4

正しいエンコーディングで構築された StreamReader を使用し、それを XmlReader.Create(TextStream) メソッドに渡すだけだと思います。

 using (var sr = new StreamReader(@"c:\temp\bad.xml", Encoding.BigEndianUnicode)) {
     using (var xr = XmlReader.Create(sr, new XmlReaderSettings())) {
         // etc...
     }
 }
于 2010-10-27T15:30:06.010 に答える
1

関連する処理命令が他にない場合は、 を設定して無視することができますXmlReaderSettings.IgnoreProcessingInstructions

于 2010-10-27T14:19:46.520 に答える