[beast] SFI: roll our own cescape function



commit 8ccc503bc6ee7a487c3d8834cf4ed028c537af52
Author: Tim Janik <timj gnu org>
Date:   Mon Oct 22 03:29:22 2012 +0200

    SFI: roll our own cescape function
    
    With Gnome bug #664830, g_strescape starts to produce "\v", which
    GScanner cannot handle. Our own cescape function avoids generating
    characters that GScanner cannot handle.

 sfi/sfiserial.cc      |   57 +++++++++++++++++++++++++++++++++++++++++-------
 sfi/tests/misctests.c |    1 +
 2 files changed, 49 insertions(+), 9 deletions(-)
---
diff --git a/sfi/sfiserial.cc b/sfi/sfiserial.cc
index 17a75f1..a14ca16 100644
--- a/sfi/sfiserial.cc
+++ b/sfi/sfiserial.cc
@@ -20,13 +20,15 @@
 #include "sfiparams.h"
 #include "sfitime.h"
 #include "sfinote.h"
+#include <stdlib.h>     // FIXME: remove "free"
 
+typedef std::string String; // FIXME
 
 /* --- parsing aids --- */
 #define MC(s)   const_cast<char*> (s)
 static const GScannerConfig storage_scanner_config = {
   MC (
-      " \t\r\n"
+      " \t\r\n\v"
       )			/* cset_skip_characters */,
   MC (
       G_CSET_a_2_z
@@ -94,6 +96,49 @@ scanner_skip_statement (GScanner *scanner,
   return G_TOKEN_NONE;
 }
 
+static String
+string_vprintf (const char *format, va_list vargs) // FIXME: move
+{
+  char *str = NULL;
+  if (vasprintf (&str, format, vargs) >= 0 && str)
+    {
+      String s = str;
+      free (str);
+      return s;
+    }
+  else
+    return format;
+}
+
+static String
+string_printf (const char *format, ...) // FIXME: move
+{
+  String str;
+  va_list args;
+  va_start (args, format);
+  str = string_vprintf (format, args);
+  va_end (args);
+  return str;
+}
+
+static String
+string_to_cescape (const String &str)   // FIXME: move
+{
+  String buffer;
+  for (String::const_iterator it = str.begin(); it != str.end(); it++)
+    {
+      uint8 d = *it;
+      if (d < 32 || d > 126 || d == '?')
+        buffer += string_printf ("\\%03o", d);
+      else if (d == '\\')
+        buffer += "\\\\";
+      else if (d == '"')
+        buffer += "\\\"";
+      else
+        buffer += d;
+    }
+  return buffer;
+}
 
 /* --- storage helpers --- */
 #define	gstring_puts(gstring, string)	g_string_append (gstring, string)
@@ -324,13 +369,7 @@ sfi_serialize_primitives (SfiSCategory scat,
 	{
 	  char *cstring = const_cast<char*> (sfi_value_get_string (value));
 	  if (cstring)
-	    {
-	      gchar *string = g_strescape (cstring, NULL);
-	      gstring_putc (gstring, '"');
-	      gstring_puts (gstring, string);
-	      gstring_putc (gstring, '"');
-	      g_free (string);
-	    }
+            gstring_puts (gstring, String ("\"" + string_to_cescape (cstring) + "\"").c_str());
 	  else
 	    gstring_puts (gstring, SFI_SERIAL_NULL_TOKEN);
 	}
@@ -340,7 +379,7 @@ sfi_serialize_primitives (SfiSCategory scat,
 	  if (sfi_serial_check_parse_null_token (scanner))
 	    sfi_value_set_string (value, NULL);
 	  else if (scanner->token == G_TOKEN_STRING)
-	    sfi_value_set_string (value, scanner->value.v_string);
+            sfi_value_set_string (value, scanner->value.v_string);
 	  else
 	    return G_TOKEN_STRING;
 	}
diff --git a/sfi/tests/misctests.c b/sfi/tests/misctests.c
index 7a2e62f..eddcbda 100644
--- a/sfi/tests/misctests.c
+++ b/sfi/tests/misctests.c
@@ -282,6 +282,7 @@ serial_pspec_check (GParamSpec *pspec,
   g_string_free (s2, TRUE);
 }
 
+// serialize @a value according to @a pspec, deserialize and assert a matching result
 static void
 serialize_cmp (GValue     *value,
 	       GParamSpec *pspec)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]