From b75e7c82b66880b04974f993c9b6a8ab49acf63a Mon Sep 17 00:00:00 2001 From: Antonius Riha Date: Sun, 7 Sep 2014 19:08:12 +0200 Subject: [PATCH] gtk: Fix Builder xml definition loading Gtk.Builder crashes when AddFromString(string) is called with a string that contains a BOM. Hence, if the buffer contains a BOM, just skip it. This fixes the crash with the Gtk# 3 project template in MonoDevelop (robpvn/MonoDevelopGtkSharp3Template). --- gtk/Builder.cs | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/gtk/Builder.cs b/gtk/Builder.cs index acf34af93..631a89579 100644 --- a/gtk/Builder.cs +++ b/gtk/Builder.cs @@ -26,8 +26,10 @@ namespace Gtk { using System; + using System.IO; using System.Reflection; using System.Runtime.InteropServices; + using System.Text; public partial class Builder { @@ -159,13 +161,7 @@ namespace Gtk { if (s == null) throw new ArgumentNullException ("s"); - int size = (int) s.Length; - byte[] buffer = new byte[size]; - s.Read (buffer, 0, size); - s.Close (); - - AddFromString(System.Text.Encoding.UTF8.GetString (buffer)); - + AddFromStream (s); TranslationDomain = translation_domain; } @@ -191,13 +187,7 @@ namespace Gtk { throw new ArgumentException ("Cannot get resource file '" + resource_name + "'", "resource_name"); - int size = (int) s.Length; - byte[] buffer = new byte[size]; - s.Read (buffer, 0, size); - s.Close (); - - AddFromString(System.Text.Encoding.UTF8.GetString (buffer)); - + AddFromStream (s); TranslationDomain = translation_domain; } @@ -368,6 +358,22 @@ namespace Gtk { } + void AddFromStream (Stream stream) + { + var size = (int)stream.Length; + var buffer = new byte[size]; + stream.Read (buffer, 0, size); + stream.Close (); + + // If buffer contains a BOM, omit it while reading, otherwise AddFromString(text) crashes + var offset = 0; + if (size >= 3 && buffer [0] == 0xEF && buffer [1] == 0xBB && buffer [2] == 0xBF) { + offset = 3; + } + + var text = Encoding.UTF8.GetString (buffer, offset, size - offset); + AddFromString (text); + } void BindFields (object target) {