Prohibit mixed glyphs/unicode buffers in deserialization
diff --git a/src/hb-buffer-deserialize-json.hh b/src/hb-buffer-deserialize-json.hh
index 64fac02..14deee9 100644
--- a/src/hb-buffer-deserialize-json.hh
+++ b/src/hb-buffer-deserialize-json.hh
@@ -39,8 +39,8 @@
 	9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, 
 	120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 
 	9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 
-	65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 93u, 
-	9u, 123u, 0u, 0u, 0
+	65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 
+	9u, 93u, 9u, 123u, 0u, 0u, 0
 };
 
 static const char _deserialize_json_key_spans[] = {
@@ -49,8 +49,8 @@
 	117, 117, 1, 1, 50, 49, 117, 117, 
 	2, 1, 50, 49, 10, 117, 117, 1, 
 	50, 49, 10, 117, 117, 1, 50, 49, 
-	58, 89, 117, 117, 1, 50, 49, 85, 
-	115, 0
+	58, 89, 117, 117, 1, 50, 49, 117, 
+	85, 115, 0
 };
 
 static const short _deserialize_json_index_offsets[] = {
@@ -60,7 +60,7 @@
 	1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680, 
 	1682, 1733, 1783, 1794, 1912, 2030, 2032, 2083, 
 	2133, 2192, 2282, 2400, 2518, 2520, 2571, 2621, 
-	2707, 2823
+	2739, 2825, 2941
 };
 
 static const char _deserialize_json_indicies[] = {
@@ -390,22 +390,37 @@
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 78, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 68, 69, 69, 69, 69, 
-	69, 69, 69, 69, 69, 1, 79, 79, 
-	79, 79, 79, 1, 1, 1, 1, 1, 
+	1, 1, 1, 79, 80, 80, 80, 80, 
+	80, 80, 80, 80, 80, 1, 73, 73, 
+	73, 73, 73, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 79, 1, 1, 
+	1, 1, 1, 1, 1, 73, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 80, 1, 1, 1, 1, 1, 1, 
+	1, 74, 1, 1, 1, 81, 81, 81, 
+	81, 81, 81, 81, 81, 81, 81, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 81, 1, 0, 0, 0, 0, 
-	0, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 0, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 75, 1, 82, 82, 82, 82, 
+	82, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 82, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 83, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	84, 1, 0, 0, 0, 0, 0, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 1, 1, 1, 1, 1, 1, 1, 
+	1, 0, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
@@ -416,22 +431,21 @@
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
 	1, 1, 1, 1, 1, 1, 1, 1, 
-	1, 1, 1, 1, 1, 1, 2, 1, 
-	1, 0
+	1, 1, 1, 1, 2, 1, 1, 0
 };
 
 static const char _deserialize_json_trans_targs[] = {
 	1, 0, 2, 2, 3, 4, 18, 24, 
 	37, 44, 5, 12, 6, 7, 8, 9, 
-	11, 9, 11, 10, 2, 47, 10, 47, 
+	11, 9, 11, 10, 2, 48, 10, 48, 
 	13, 14, 15, 16, 17, 16, 17, 10, 
-	2, 47, 19, 20, 21, 22, 23, 10, 
-	2, 47, 23, 25, 31, 26, 27, 28, 
-	29, 30, 29, 30, 10, 2, 47, 32, 
+	2, 48, 19, 20, 21, 22, 23, 10, 
+	2, 48, 23, 25, 31, 26, 27, 28, 
+	29, 30, 29, 30, 10, 2, 48, 32, 
 	33, 34, 35, 36, 35, 36, 10, 2, 
-	47, 38, 39, 40, 42, 43, 41, 10, 
-	41, 10, 2, 47, 43, 45, 46, 47, 
-	48, 49
+	48, 38, 39, 40, 42, 43, 41, 10, 
+	41, 10, 2, 48, 43, 45, 46, 42, 
+	47, 47, 48, 49, 50
 };
 
 static const char _deserialize_json_trans_actions[] = {
@@ -443,19 +457,19 @@
 	8, 9, 0, 0, 0, 0, 0, 2, 
 	2, 2, 0, 0, 10, 10, 11, 0, 
 	0, 2, 2, 2, 0, 0, 12, 12, 
-	13, 0, 0, 0, 2, 2, 2, 14, 
-	0, 15, 15, 16, 0, 0, 0, 0, 
-	0, 0
+	13, 0, 0, 0, 14, 14, 2, 15, 
+	0, 16, 16, 17, 18, 0, 0, 19, 
+	19, 20, 0, 0, 0
 };
 
 static const int deserialize_json_start = 1;
-static const int deserialize_json_first_final = 47;
+static const int deserialize_json_first_final = 48;
 static const int deserialize_json_error = 0;
 
 static const int deserialize_json_en_main = 1;
 
 
-#line 98 "hb-buffer-deserialize-json.rl"
+#line 122 "hb-buffer-deserialize-json.rl"
 
 
 static hb_bool_t
@@ -482,12 +496,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
   
-#line 486 "hb-buffer-deserialize-json.hh"
+#line 500 "hb-buffer-deserialize-json.hh"
 	{
 	cs = deserialize_json_start;
 	}
 
-#line 491 "hb-buffer-deserialize-json.hh"
+#line 505 "hb-buffer-deserialize-json.hh"
 	{
 	int _slen;
 	int _trans;
@@ -535,41 +549,117 @@
 	tok = p;
 }
 	break;
-	case 14:
+	case 18:
 #line 55 "hb-buffer-deserialize-json.rl"
 	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
+	break;
+	case 20:
+#line 67 "hb-buffer-deserialize-json.rl"
+	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+  }
+}
+	break;
+	case 16:
+#line 86 "hb-buffer-deserialize-json.rl"
+	{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
+	break;
+	case 8:
+#line 87 "hb-buffer-deserialize-json.rl"
+	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
+	break;
+	case 10:
+#line 88 "hb-buffer-deserialize-json.rl"
+	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
+	break;
+	case 12:
+#line 89 "hb-buffer-deserialize-json.rl"
+	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
+	break;
+	case 3:
+#line 90 "hb-buffer-deserialize-json.rl"
+	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
+	break;
+	case 6:
+#line 91 "hb-buffer-deserialize-json.rl"
+	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
+	break;
+	case 14:
+#line 51 "hb-buffer-deserialize-json.rl"
+	{
+	tok = p;
+}
+#line 55 "hb-buffer-deserialize-json.rl"
+	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
+	break;
+	case 19:
+#line 51 "hb-buffer-deserialize-json.rl"
+	{
+	tok = p;
+}
+#line 67 "hb-buffer-deserialize-json.rl"
+	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+  }
+}
+	break;
+	case 15:
+#line 79 "hb-buffer-deserialize-json.rl"
+	{
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
 	  return false;
 }
+#line 55 "hb-buffer-deserialize-json.rl"
+	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
 	break;
-	case 15:
-#line 62 "hb-buffer-deserialize-json.rl"
-	{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
-	break;
-	case 8:
-#line 63 "hb-buffer-deserialize-json.rl"
-	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
-	break;
-	case 10:
-#line 64 "hb-buffer-deserialize-json.rl"
-	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
-	break;
-	case 12:
-#line 65 "hb-buffer-deserialize-json.rl"
-	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
-	break;
-	case 3:
-#line 66 "hb-buffer-deserialize-json.rl"
-	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
-	break;
-	case 6:
-#line 67 "hb-buffer-deserialize-json.rl"
-	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
-	break;
-	case 16:
-#line 62 "hb-buffer-deserialize-json.rl"
+	case 17:
+#line 86 "hb-buffer-deserialize-json.rl"
 	{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
 #line 43 "hb-buffer-deserialize-json.rl"
 	{
@@ -581,7 +671,7 @@
 }
 	break;
 	case 9:
-#line 63 "hb-buffer-deserialize-json.rl"
+#line 87 "hb-buffer-deserialize-json.rl"
 	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
 #line 43 "hb-buffer-deserialize-json.rl"
 	{
@@ -593,7 +683,7 @@
 }
 	break;
 	case 11:
-#line 64 "hb-buffer-deserialize-json.rl"
+#line 88 "hb-buffer-deserialize-json.rl"
 	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
 #line 43 "hb-buffer-deserialize-json.rl"
 	{
@@ -605,7 +695,7 @@
 }
 	break;
 	case 13:
-#line 65 "hb-buffer-deserialize-json.rl"
+#line 89 "hb-buffer-deserialize-json.rl"
 	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
 #line 43 "hb-buffer-deserialize-json.rl"
 	{
@@ -617,7 +707,7 @@
 }
 	break;
 	case 4:
-#line 66 "hb-buffer-deserialize-json.rl"
+#line 90 "hb-buffer-deserialize-json.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 #line 43 "hb-buffer-deserialize-json.rl"
 	{
@@ -629,7 +719,7 @@
 }
 	break;
 	case 7:
-#line 67 "hb-buffer-deserialize-json.rl"
+#line 91 "hb-buffer-deserialize-json.rl"
 	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
 #line 43 "hb-buffer-deserialize-json.rl"
 	{
@@ -640,7 +730,7 @@
 	*end_ptr = p;
 }
 	break;
-#line 644 "hb-buffer-deserialize-json.hh"
+#line 734 "hb-buffer-deserialize-json.hh"
 	}
 
 _again:
@@ -652,7 +742,7 @@
 	_out: {}
 	}
 
-#line 126 "hb-buffer-deserialize-json.rl"
+#line 150 "hb-buffer-deserialize-json.rl"
 
 
   *end_ptr = p;
diff --git a/src/hb-buffer-deserialize-json.rl b/src/hb-buffer-deserialize-json.rl
index 336a5ea..14e1bb4 100644
--- a/src/hb-buffer-deserialize-json.rl
+++ b/src/hb-buffer-deserialize-json.rl
@@ -52,6 +52,30 @@
 	tok = p;
 }
 
+action ensure_glyphs {
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
+
+action ensure_unicode {
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+  }
+}
+
 action parse_glyph {
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
@@ -78,8 +102,8 @@
 glyph_string   = '"' (glyph_name >tok %parse_glyph) '"';
 glyph_number = (glyph_id >tok %parse_gid);
 
-glyph	= "\"g\""  colon (glyph_string | glyph_number);
-codepoint	= "\"u\""  colon glyph_number;
+glyph	= "\"g\""  colon (glyph_string | glyph_number) @ensure_glyphs;
+codepoint	= "\"u\""  colon glyph_number @ensure_unicode;
 cluster	= "\"cl\"" colon (unum >tok %parse_cluster);
 xoffset	= "\"dx\"" colon (num >tok %parse_x_offset);
 yoffset	= "\"dy\"" colon (num >tok %parse_y_offset);
diff --git a/src/hb-buffer-deserialize-text.hh b/src/hb-buffer-deserialize-text.hh
index 90275b8..c437718 100644
--- a/src/hb-buffer-deserialize-text.hh
+++ b/src/hb-buffer-deserialize-text.hh
@@ -409,17 +409,17 @@
 	2, 2, 2, 0, 0, 5, 0, 6, 
 	5, 5, 0, 0, 0, 7, 7, 7, 
 	0, 8, 9, 9, 9, 8, 8, 0, 
-	0, 0, 10, 11, 10, 10, 12, 12, 
-	12, 7, 13, 13, 7, 14, 15, 14, 
-	14, 0, 0
+	0, 10, 11, 12, 11, 11, 13, 13, 
+	13, 7, 14, 14, 7, 15, 16, 15, 
+	15, 0, 10
 };
 
 static const char _deserialize_text_eof_actions[] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 0, 5, 0, 0, 0, 
-	7, 7, 8, 0, 0, 8, 10, 12, 
-	12, 10, 7, 14, 14, 7, 8
+	7, 7, 8, 0, 0, 8, 11, 13, 
+	13, 11, 7, 15, 15, 7, 8
 };
 
 static const int deserialize_text_start = 1;
@@ -429,7 +429,7 @@
 static const int deserialize_text_en_main = 1;
 
 
-#line 100 "hb-buffer-deserialize-text.rl"
+#line 124 "hb-buffer-deserialize-text.rl"
 
 
 static hb_bool_t
@@ -482,22 +482,29 @@
 		goto _again;
 
 	switch ( _deserialize_text_trans_actions[_trans] ) {
-	case 1:
-#line 38 "hb-buffer-deserialize-text.rl"
-	{
-	memset (&info, 0, sizeof (info));
-	memset (&pos , 0, sizeof (pos ));
-}
-	break;
 	case 2:
 #line 51 "hb-buffer-deserialize-text.rl"
 	{
 	tok = p;
 }
 	break;
-	case 9:
+	case 10:
 #line 55 "hb-buffer-deserialize-text.rl"
 	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
+	break;
+	case 9:
+#line 79 "hb-buffer-deserialize-text.rl"
+	{
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
 					&info.codepoint))
@@ -505,38 +512,46 @@
 }
 	break;
 	case 6:
-#line 62 "hb-buffer-deserialize-text.rl"
+#line 86 "hb-buffer-deserialize-text.rl"
 	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
 	break;
-	case 13:
-#line 64 "hb-buffer-deserialize-text.rl"
+	case 14:
+#line 88 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
 	break;
 	case 4:
-#line 65 "hb-buffer-deserialize-text.rl"
+#line 89 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_offset )) return false; }
 	break;
-	case 15:
-#line 66 "hb-buffer-deserialize-text.rl"
+	case 16:
+#line 90 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
 	break;
-	case 11:
-#line 67 "hb-buffer-deserialize-text.rl"
+	case 12:
+#line 91 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 	break;
-	case 3:
+	case 1:
 #line 38 "hb-buffer-deserialize-text.rl"
 	{
 	memset (&info, 0, sizeof (info));
 	memset (&pos , 0, sizeof (pos ));
 }
-#line 51 "hb-buffer-deserialize-text.rl"
+#line 67 "hb-buffer-deserialize-text.rl"
 	{
-	tok = p;
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+  }
 }
 	break;
 	case 8:
-#line 55 "hb-buffer-deserialize-text.rl"
+#line 79 "hb-buffer-deserialize-text.rl"
 	{
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
@@ -553,7 +568,7 @@
 }
 	break;
 	case 5:
-#line 62 "hb-buffer-deserialize-text.rl"
+#line 86 "hb-buffer-deserialize-text.rl"
 	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -565,7 +580,7 @@
 }
 	break;
 	case 7:
-#line 64 "hb-buffer-deserialize-text.rl"
+#line 88 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -576,8 +591,8 @@
 	*end_ptr = p;
 }
 	break;
-	case 14:
-#line 66 "hb-buffer-deserialize-text.rl"
+	case 15:
+#line 90 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -588,8 +603,8 @@
 	*end_ptr = p;
 }
 	break;
-	case 10:
-#line 67 "hb-buffer-deserialize-text.rl"
+	case 11:
+#line 91 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -600,8 +615,8 @@
 	*end_ptr = p;
 }
 	break;
-	case 12:
-#line 68 "hb-buffer-deserialize-text.rl"
+	case 13:
+#line 92 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -612,7 +627,30 @@
 	*end_ptr = p;
 }
 	break;
-#line 616 "hb-buffer-deserialize-text.hh"
+	case 3:
+#line 38 "hb-buffer-deserialize-text.rl"
+	{
+	memset (&info, 0, sizeof (info));
+	memset (&pos , 0, sizeof (pos ));
+}
+#line 51 "hb-buffer-deserialize-text.rl"
+	{
+	tok = p;
+}
+#line 55 "hb-buffer-deserialize-text.rl"
+	{
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
+	break;
+#line 654 "hb-buffer-deserialize-text.hh"
 	}
 
 _again:
@@ -625,7 +663,7 @@
 	{
 	switch ( _deserialize_text_eof_actions[cs] ) {
 	case 8:
-#line 55 "hb-buffer-deserialize-text.rl"
+#line 79 "hb-buffer-deserialize-text.rl"
 	{
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
@@ -642,7 +680,7 @@
 }
 	break;
 	case 5:
-#line 62 "hb-buffer-deserialize-text.rl"
+#line 86 "hb-buffer-deserialize-text.rl"
 	{if (!parse_hex (tok, p, &info.codepoint )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -654,7 +692,7 @@
 }
 	break;
 	case 7:
-#line 64 "hb-buffer-deserialize-text.rl"
+#line 88 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_uint (tok, p, &info.cluster )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -665,8 +703,8 @@
 	*end_ptr = p;
 }
 	break;
-	case 14:
-#line 66 "hb-buffer-deserialize-text.rl"
+	case 15:
+#line 90 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_offset )) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -677,8 +715,8 @@
 	*end_ptr = p;
 }
 	break;
-	case 10:
-#line 67 "hb-buffer-deserialize-text.rl"
+	case 11:
+#line 91 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.x_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -689,8 +727,8 @@
 	*end_ptr = p;
 }
 	break;
-	case 12:
-#line 68 "hb-buffer-deserialize-text.rl"
+	case 13:
+#line 92 "hb-buffer-deserialize-text.rl"
 	{ if (!parse_int  (tok, p, &pos.y_advance)) return false; }
 #line 43 "hb-buffer-deserialize-text.rl"
 	{
@@ -701,14 +739,14 @@
 	*end_ptr = p;
 }
 	break;
-#line 705 "hb-buffer-deserialize-text.hh"
+#line 743 "hb-buffer-deserialize-text.hh"
 	}
 	}
 
 	_out: {}
 	}
 
-#line 124 "hb-buffer-deserialize-text.rl"
+#line 148 "hb-buffer-deserialize-text.rl"
 
 
   *end_ptr = p;
diff --git a/src/hb-buffer-deserialize-text.rl b/src/hb-buffer-deserialize-text.rl
index f01e2d3..dd3e972 100644
--- a/src/hb-buffer-deserialize-text.rl
+++ b/src/hb-buffer-deserialize-text.rl
@@ -52,6 +52,30 @@
 	tok = p;
 }
 
+action ensure_glyphs {
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
+  }
+}
+
+action ensure_unicode {
+  if (unlikely (buffer->content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
+  {
+    if (buffer->content_type != HB_BUFFER_CONTENT_TYPE_INVALID) {
+    	buffer->clear();
+      return false;
+    }
+    assert (buffer->len == 0);
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
+  }
+}
+
 action parse_glyph {
 	if (!hb_font_glyph_from_string (font,
 					tok, p - tok,
@@ -73,13 +97,13 @@
 glyph_id = unum;
 glyph_name = alpha (alnum|'_'|'.'|'-')*;
 
-glyph	= (glyph_id | glyph_name) >tok %parse_glyph;
+glyph	= (glyph_id | glyph_name) >tok @ensure_glyphs %parse_glyph;
 cluster	= '=' (unum >tok %parse_cluster);
 offsets	= '@' (num >tok %parse_x_offset)   ',' (num >tok %parse_y_offset );
 advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?;
 
 codepoint = xdigit+ >tok %parse_hexdigits;
-unicode_id = 'U' '+'  >clear_item codepoint cluster? %add_item;
+unicode_id = 'U' '+'  >clear_item @ensure_unicode codepoint cluster? %add_item;
 
 item	=
 	(
diff --git a/test/api/test-buffer.c b/test/api/test-buffer.c
index 1418cf8..b3cd1bf 100644
--- a/test/api/test-buffer.c
+++ b/test/api/test-buffer.c
@@ -35,380 +35,380 @@
 
 
 typedef enum {
-  BUFFER_EMPTY,
-  BUFFER_ONE_BY_ONE,
-  BUFFER_UTF32,
-  BUFFER_UTF16,
-  BUFFER_UTF8,
-  BUFFER_NUM_TYPES,
+	BUFFER_EMPTY,
+	BUFFER_ONE_BY_ONE,
+	BUFFER_UTF32,
+	BUFFER_UTF16,
+	BUFFER_UTF8,
+	BUFFER_NUM_TYPES,
 } buffer_type_t;
 
 static const char *buffer_names[] = {
-  "empty",
-  "one-by-one",
-  "utf32",
-  "utf16",
-  "utf8"
+	"empty",
+	"one-by-one",
+	"utf32",
+	"utf16",
+	"utf8"
 };
 
 typedef struct
 {
-  hb_buffer_t *buffer;
+	hb_buffer_t *buffer;
 } fixture_t;
 
 static void
 fixture_init (fixture_t *fixture, gconstpointer user_data)
 {
-  hb_buffer_t *b;
-  unsigned int i;
+	hb_buffer_t *b;
+	unsigned int i;
 
-  b = fixture->buffer = hb_buffer_create ();
+	b = fixture->buffer = hb_buffer_create ();
 
-  switch (GPOINTER_TO_INT (user_data))
-  {
-    case BUFFER_EMPTY:
-      break;
+	switch (GPOINTER_TO_INT (user_data))
+	{
+		case BUFFER_EMPTY:
+			break;
 
-    case BUFFER_ONE_BY_ONE:
-      for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++)
+		case BUFFER_ONE_BY_ONE:
+			for (i = 1; i < G_N_ELEMENTS (utf32) - 1; i++)
 	hb_buffer_add (b, utf32[i], i);
-      break;
+			break;
 
-    case BUFFER_UTF32:
-      hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
-      break;
+		case BUFFER_UTF32:
+			hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
+			break;
 
-    case BUFFER_UTF16:
-      hb_buffer_add_utf16 (b, utf16, G_N_ELEMENTS (utf16), 1, G_N_ELEMENTS (utf16) - 2);
-      break;
+		case BUFFER_UTF16:
+			hb_buffer_add_utf16 (b, utf16, G_N_ELEMENTS (utf16), 1, G_N_ELEMENTS (utf16) - 2);
+			break;
 
-    case BUFFER_UTF8:
-      hb_buffer_add_utf8  (b, utf8,  G_N_ELEMENTS (utf8),  1, G_N_ELEMENTS (utf8)  - 2);
-      break;
+		case BUFFER_UTF8:
+			hb_buffer_add_utf8  (b, utf8,  G_N_ELEMENTS (utf8),  1, G_N_ELEMENTS (utf8)  - 2);
+			break;
 
-    default:
-      g_assert_not_reached ();
-  }
+		default:
+			g_assert_not_reached ();
+	}
 }
 
 static void
 fixture_finish (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
 {
-  hb_buffer_destroy (fixture->buffer);
+	hb_buffer_destroy (fixture->buffer);
 }
 
 
 static void
 test_buffer_properties (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
 {
-  hb_buffer_t *b = fixture->buffer;
-  hb_unicode_funcs_t *ufuncs;
+	hb_buffer_t *b = fixture->buffer;
+	hb_unicode_funcs_t *ufuncs;
 
-  /* test default properties */
+	/* test default properties */
 
-  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
-  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
-  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
-  g_assert (hb_buffer_get_language (b) == NULL);
+	g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
+	g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
+	g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
+	g_assert (hb_buffer_get_language (b) == NULL);
 
 
-  /* test property changes are retained */
-  ufuncs = hb_unicode_funcs_create (NULL);
-  hb_buffer_set_unicode_funcs (b, ufuncs);
-  hb_unicode_funcs_destroy (ufuncs);
-  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
+	/* test property changes are retained */
+	ufuncs = hb_unicode_funcs_create (NULL);
+	hb_buffer_set_unicode_funcs (b, ufuncs);
+	hb_unicode_funcs_destroy (ufuncs);
+	g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
 
-  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
-  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
+	hb_buffer_set_direction (b, HB_DIRECTION_RTL);
+	g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
 
-  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
-  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
+	hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
+	g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
 
-  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
-  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
+	hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
+	g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
 
-  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
-  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
+	hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
+	g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
 
-  hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
-  g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
+	hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
+	g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
 
 
-  /* test clear_contents clears all these properties: */
+	/* test clear_contents clears all these properties: */
 
-  hb_buffer_clear_contents (b);
+	hb_buffer_clear_contents (b);
 
-  g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
-  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
-  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
-  g_assert (hb_buffer_get_language (b) == NULL);
+	g_assert (hb_buffer_get_unicode_funcs (b) == ufuncs);
+	g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
+	g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
+	g_assert (hb_buffer_get_language (b) == NULL);
 
-  /* but not these: */
+	/* but not these: */
 
-  g_assert (hb_buffer_get_flags (b) != HB_BUFFER_FLAGS_DEFAULT);
-  g_assert (hb_buffer_get_replacement_codepoint (b) != HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
+	g_assert (hb_buffer_get_flags (b) != HB_BUFFER_FLAGS_DEFAULT);
+	g_assert (hb_buffer_get_replacement_codepoint (b) != HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
 
 
-  /* test reset clears all properties */
+	/* test reset clears all properties */
 
-  hb_buffer_set_direction (b, HB_DIRECTION_RTL);
-  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
+	hb_buffer_set_direction (b, HB_DIRECTION_RTL);
+	g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_RTL);
 
-  hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
-  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
+	hb_buffer_set_script (b, HB_SCRIPT_ARABIC);
+	g_assert (hb_buffer_get_script (b) == HB_SCRIPT_ARABIC);
 
-  hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
-  g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
+	hb_buffer_set_language (b, hb_language_from_string ("fa", -1));
+	g_assert (hb_buffer_get_language (b) == hb_language_from_string ("Fa", -1));
 
-  hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
-  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
+	hb_buffer_set_flags (b, HB_BUFFER_FLAG_BOT);
+	g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAG_BOT);
 
-  hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
-  g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
+	hb_buffer_set_replacement_codepoint (b, (unsigned int) -1);
+	g_assert (hb_buffer_get_replacement_codepoint (b) == (unsigned int) -1);
 
-  hb_buffer_reset (b);
+	hb_buffer_reset (b);
 
-  g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
-  g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
-  g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
-  g_assert (hb_buffer_get_language (b) == NULL);
-  g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT);
-  g_assert (hb_buffer_get_replacement_codepoint (b) == HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
+	g_assert (hb_buffer_get_unicode_funcs (b) == hb_unicode_funcs_get_default ());
+	g_assert (hb_buffer_get_direction (b) == HB_DIRECTION_INVALID);
+	g_assert (hb_buffer_get_script (b) == HB_SCRIPT_INVALID);
+	g_assert (hb_buffer_get_language (b) == NULL);
+	g_assert (hb_buffer_get_flags (b) == HB_BUFFER_FLAGS_DEFAULT);
+	g_assert (hb_buffer_get_replacement_codepoint (b) == HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
 }
 
 static void
 test_buffer_contents (fixture_t *fixture, gconstpointer user_data)
 {
-  hb_buffer_t *b = fixture->buffer;
-  unsigned int i, len, len2;
-  buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
-  hb_glyph_info_t *glyphs;
+	hb_buffer_t *b = fixture->buffer;
+	unsigned int i, len, len2;
+	buffer_type_t buffer_type = GPOINTER_TO_INT (user_data);
+	hb_glyph_info_t *glyphs;
 
-  if (buffer_type == BUFFER_EMPTY) {
-    g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
-    return;
-  }
+	if (buffer_type == BUFFER_EMPTY) {
+		g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+		return;
+	}
 
-  len = hb_buffer_get_length (b);
-  hb_buffer_get_glyph_infos (b, NULL); /* test NULL */
-  glyphs = hb_buffer_get_glyph_infos (b, &len2);
-  g_assert_cmpint (len, ==, len2);
-  g_assert_cmpint (len, ==, 5);
+	len = hb_buffer_get_length (b);
+	hb_buffer_get_glyph_infos (b, NULL); /* test NULL */
+	glyphs = hb_buffer_get_glyph_infos (b, &len2);
+	g_assert_cmpint (len, ==, len2);
+	g_assert_cmpint (len, ==, 5);
 
-  for (i = 0; i < len; i++) {
-    g_assert_cmphex (glyphs[i].mask,      ==, 0);
-    g_assert_cmphex (glyphs[i].var1.u32,  ==, 0);
-    g_assert_cmphex (glyphs[i].var2.u32,  ==, 0);
-  }
+	for (i = 0; i < len; i++) {
+		g_assert_cmphex (glyphs[i].mask,      ==, 0);
+		g_assert_cmphex (glyphs[i].var1.u32,  ==, 0);
+		g_assert_cmphex (glyphs[i].var2.u32,  ==, 0);
+	}
 
-  for (i = 0; i < len; i++) {
-    unsigned int cluster;
-    cluster = 1+i;
-    if (i >= 2) {
-      if (buffer_type == BUFFER_UTF16)
+	for (i = 0; i < len; i++) {
+		unsigned int cluster;
+		cluster = 1+i;
+		if (i >= 2) {
+			if (buffer_type == BUFFER_UTF16)
 	cluster++;
-      else if (buffer_type == BUFFER_UTF8)
+			else if (buffer_type == BUFFER_UTF8)
 	cluster += 3;
-    }
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
-    g_assert_cmphex (glyphs[i].cluster,   ==, cluster);
-  }
+		}
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+		g_assert_cmphex (glyphs[i].cluster,   ==, cluster);
+	}
 
-  /* reverse, test, and reverse back */
+	/* reverse, test, and reverse back */
 
-  hb_buffer_reverse (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
+	hb_buffer_reverse (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
 
-  hb_buffer_reverse (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+	hb_buffer_reverse (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
 
-  /* reverse_clusters works same as reverse for now since each codepoint is
-   * in its own cluster */
+	/* reverse_clusters works same as reverse for now since each codepoint is
+	 * in its own cluster */
 
-  hb_buffer_reverse_clusters (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
+	hb_buffer_reverse_clusters (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
 
-  hb_buffer_reverse_clusters (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+	hb_buffer_reverse_clusters (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
 
-  /* now form a cluster and test again */
-  glyphs[2].cluster = glyphs[1].cluster;
+	/* now form a cluster and test again */
+	glyphs[2].cluster = glyphs[1].cluster;
 
-  /* reverse, test, and reverse back */
+	/* reverse, test, and reverse back */
 
-  hb_buffer_reverse (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
+	hb_buffer_reverse (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[len-i]);
 
-  hb_buffer_reverse (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+	hb_buffer_reverse (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
 
-  /* reverse_clusters twice still should return the original string,
-   * but when applied once, the 1-2 cluster should be retained. */
+	/* reverse_clusters twice still should return the original string,
+	 * but when applied once, the 1-2 cluster should be retained. */
 
-  hb_buffer_reverse_clusters (b);
-  for (i = 0; i < len; i++) {
-    unsigned int j = len-1-i;
-    if (j == 1)
-      j = 2;
-    else if (j == 2)
-      j = 1;
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+j]);
-  }
+	hb_buffer_reverse_clusters (b);
+	for (i = 0; i < len; i++) {
+		unsigned int j = len-1-i;
+		if (j == 1)
+			j = 2;
+		else if (j == 2)
+			j = 1;
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+j]);
+	}
 
-  hb_buffer_reverse_clusters (b);
-  for (i = 0; i < len; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+	hb_buffer_reverse_clusters (b);
+	for (i = 0; i < len; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
 
 
-  /* test setting length */
+	/* test setting length */
 
-  /* enlarge */
-  g_assert (hb_buffer_set_length (b, 10));
-  glyphs = hb_buffer_get_glyph_infos (b, NULL);
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 10);
-  for (i = 0; i < 5; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
-  for (i = 5; i < 10; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, 0);
-  /* shrink */
-  g_assert (hb_buffer_set_length (b, 3));
-  glyphs = hb_buffer_get_glyph_infos (b, NULL);
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 3);
-  for (i = 0; i < 3; i++)
-    g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+	/* enlarge */
+	g_assert (hb_buffer_set_length (b, 10));
+	glyphs = hb_buffer_get_glyph_infos (b, NULL);
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 10);
+	for (i = 0; i < 5; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
+	for (i = 5; i < 10; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, 0);
+	/* shrink */
+	g_assert (hb_buffer_set_length (b, 3));
+	glyphs = hb_buffer_get_glyph_infos (b, NULL);
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 3);
+	for (i = 0; i < 3; i++)
+		g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
 
 
-  g_assert (hb_buffer_allocation_successful (b));
+	g_assert (hb_buffer_allocation_successful (b));
 
 
-  /* test reset clears content */
+	/* test reset clears content */
 
-  hb_buffer_reset (b);
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	hb_buffer_reset (b);
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
 }
 
 static void
 test_buffer_positions (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
 {
-  hb_buffer_t *b = fixture->buffer;
-  unsigned int i, len, len2;
-  hb_glyph_position_t *positions;
+	hb_buffer_t *b = fixture->buffer;
+	unsigned int i, len, len2;
+	hb_glyph_position_t *positions;
 
-  /* Without shaping, positions should all be zero */
-  len = hb_buffer_get_length (b);
-  hb_buffer_get_glyph_positions (b, NULL); /* test NULL */
-  positions = hb_buffer_get_glyph_positions (b, &len2);
-  g_assert_cmpint (len, ==, len2);
-  for (i = 0; i < len; i++) {
-    g_assert_cmpint (0, ==, positions[i].x_advance);
-    g_assert_cmpint (0, ==, positions[i].y_advance);
-    g_assert_cmpint (0, ==, positions[i].x_offset);
-    g_assert_cmpint (0, ==, positions[i].y_offset);
-    g_assert_cmpint (0, ==, positions[i].var.i32);
-  }
+	/* Without shaping, positions should all be zero */
+	len = hb_buffer_get_length (b);
+	hb_buffer_get_glyph_positions (b, NULL); /* test NULL */
+	positions = hb_buffer_get_glyph_positions (b, &len2);
+	g_assert_cmpint (len, ==, len2);
+	for (i = 0; i < len; i++) {
+		g_assert_cmpint (0, ==, positions[i].x_advance);
+		g_assert_cmpint (0, ==, positions[i].y_advance);
+		g_assert_cmpint (0, ==, positions[i].x_offset);
+		g_assert_cmpint (0, ==, positions[i].y_offset);
+		g_assert_cmpint (0, ==, positions[i].var.i32);
+	}
 
-  /* test reset clears content */
-  hb_buffer_reset (b);
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	/* test reset clears content */
+	hb_buffer_reset (b);
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
 }
 
 static void
 test_buffer_allocation (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
 {
-  hb_buffer_t *b = fixture->buffer;
+	hb_buffer_t *b = fixture->buffer;
 
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
 
-  g_assert (hb_buffer_pre_allocate (b, 100));
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
-  g_assert (hb_buffer_allocation_successful (b));
+	g_assert (hb_buffer_pre_allocate (b, 100));
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	g_assert (hb_buffer_allocation_successful (b));
 
-  /* lets try a huge allocation, make sure it fails */
-  g_assert (!hb_buffer_pre_allocate (b, (unsigned int) -1));
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
-  g_assert (!hb_buffer_allocation_successful (b));
+	/* lets try a huge allocation, make sure it fails */
+	g_assert (!hb_buffer_pre_allocate (b, (unsigned int) -1));
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	g_assert (!hb_buffer_allocation_successful (b));
 
-  /* small one again */
-  g_assert (hb_buffer_pre_allocate (b, 50));
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
-  g_assert (!hb_buffer_allocation_successful (b));
+	/* small one again */
+	g_assert (hb_buffer_pre_allocate (b, 50));
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	g_assert (!hb_buffer_allocation_successful (b));
 
-  hb_buffer_reset (b);
-  g_assert (hb_buffer_allocation_successful (b));
+	hb_buffer_reset (b);
+	g_assert (hb_buffer_allocation_successful (b));
 
-  /* all allocation and size  */
-  g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 + 1));
-  g_assert (!hb_buffer_allocation_successful (b));
+	/* all allocation and size  */
+	g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 + 1));
+	g_assert (!hb_buffer_allocation_successful (b));
 
-  hb_buffer_reset (b);
-  g_assert (hb_buffer_allocation_successful (b));
+	hb_buffer_reset (b);
+	g_assert (hb_buffer_allocation_successful (b));
 
-  /* technically, this one can actually pass on 64bit machines, but
-   * I'm doubtful that any malloc allows 4GB allocations at a time.
-   * But let's only enable it on a 32-bit machine. */
-  if (sizeof (long) == 4) {
-    g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 - 1));
-    g_assert (!hb_buffer_allocation_successful (b));
-  }
+	/* technically, this one can actually pass on 64bit machines, but
+	 * I'm doubtful that any malloc allows 4GB allocations at a time.
+	 * But let's only enable it on a 32-bit machine. */
+	if (sizeof (long) == 4) {
+		g_assert (!hb_buffer_pre_allocate (b, ((unsigned int) -1) / 20 - 1));
+		g_assert (!hb_buffer_allocation_successful (b));
+	}
 
-  hb_buffer_reset (b);
-  g_assert (hb_buffer_allocation_successful (b));
+	hb_buffer_reset (b);
+	g_assert (hb_buffer_allocation_successful (b));
 }
 
 
 typedef struct {
-  const char utf8[8];
-  const uint32_t codepoints[8];
+	const char utf8[8];
+	const uint32_t codepoints[8];
 } utf8_conversion_test_t;
 
 /* note: we skip the first and last byte when adding to buffer */
 static const utf8_conversion_test_t utf8_conversion_tests[] = {
-  {"a\303\207", {(hb_codepoint_t) -1}},
-  {"a\303\207b", {0xC7}},
-  {"ab\303cd", {'b', (hb_codepoint_t) -1, 'c'}},
-  {"ab\303\302\301cd", {'b', (hb_codepoint_t) -1, (hb_codepoint_t) -1, (hb_codepoint_t) -1, 'c'}}
+	{"a\303\207", {(hb_codepoint_t) -1}},
+	{"a\303\207b", {0xC7}},
+	{"ab\303cd", {'b', (hb_codepoint_t) -1, 'c'}},
+	{"ab\303\302\301cd", {'b', (hb_codepoint_t) -1, (hb_codepoint_t) -1, (hb_codepoint_t) -1, 'c'}}
 };
 
 static void
 test_buffer_utf8_conversion (void)
 {
-  hb_buffer_t *b;
-  unsigned int chars, i, j, len;
+	hb_buffer_t *b;
+	unsigned int chars, i, j, len;
 
-  b = hb_buffer_create ();
-  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
+	b = hb_buffer_create ();
+	hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
 
-  for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
-  {
-    unsigned int bytes;
-    hb_glyph_info_t *glyphs;
-    const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
-    char *escaped;
+	for (i = 0; i < G_N_ELEMENTS (utf8_conversion_tests); i++)
+	{
+		unsigned int bytes;
+		hb_glyph_info_t *glyphs;
+		const utf8_conversion_test_t *test = &utf8_conversion_tests[i];
+		char *escaped;
 
-    escaped = g_strescape (test->utf8, NULL);
-    g_test_message ("UTF-8 test #%d: %s", i, escaped);
-    g_free (escaped);
+		escaped = g_strescape (test->utf8, NULL);
+		g_test_message ("UTF-8 test #%d: %s", i, escaped);
+		g_free (escaped);
 
-    bytes = strlen (test->utf8);
-    for (chars = 0; test->codepoints[chars]; chars++)
-      ;
+		bytes = strlen (test->utf8);
+		for (chars = 0; test->codepoints[chars]; chars++)
+			;
 
-    hb_buffer_clear_contents (b);
-    hb_buffer_add_utf8 (b, test->utf8, bytes,  1, bytes - 2);
+		hb_buffer_clear_contents (b);
+		hb_buffer_add_utf8 (b, test->utf8, bytes,  1, bytes - 2);
 
-    glyphs = hb_buffer_get_glyph_infos (b, &len);
-    g_assert_cmpint (len, ==, chars);
-    for (j = 0; j < chars; j++)
-      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
-  }
+		glyphs = hb_buffer_get_glyph_infos (b, &len);
+		g_assert_cmpint (len, ==, chars);
+		for (j = 0; j < chars; j++)
+			g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
+	}
 
-  hb_buffer_destroy (b);
+	hb_buffer_destroy (b);
 }
 
 
@@ -417,513 +417,522 @@
  * with relicensing permission from Matthias Clasen. */
 
 typedef struct {
-  const char *utf8;
-  int max_len;
-  unsigned int offset;
-  gboolean valid;
+	const char *utf8;
+	int max_len;
+	unsigned int offset;
+	gboolean valid;
 } utf8_validity_test_t;
 
 static const utf8_validity_test_t utf8_validity_tests[] = {
-  /* some tests to check max_len handling */
-  /* length 1 */
-  { "abcde", -1, 5, TRUE },
-  { "abcde", 3, 3, TRUE },
-  { "abcde", 5, 5, TRUE },
-  /* length 2 */
-  { "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE },
-  { "\xc2\xa9\xc2\xa9\xc2\xa9",  1, 0, FALSE },
-  { "\xc2\xa9\xc2\xa9\xc2\xa9",  2, 2, TRUE },
-  { "\xc2\xa9\xc2\xa9\xc2\xa9",  3, 2, FALSE },
-  { "\xc2\xa9\xc2\xa9\xc2\xa9",  4, 4, TRUE },
-  { "\xc2\xa9\xc2\xa9\xc2\xa9",  5, 4, FALSE },
-  { "\xc2\xa9\xc2\xa9\xc2\xa9",  6, 6, TRUE },
-  /* length 3 */
-  { "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE },
-  { "\xe2\x89\xa0\xe2\x89\xa0",  1, 0, FALSE },
-  { "\xe2\x89\xa0\xe2\x89\xa0",  2, 0, FALSE },
-  { "\xe2\x89\xa0\xe2\x89\xa0",  3, 3, TRUE },
-  { "\xe2\x89\xa0\xe2\x89\xa0",  4, 3, FALSE },
-  { "\xe2\x89\xa0\xe2\x89\xa0",  5, 3, FALSE },
-  { "\xe2\x89\xa0\xe2\x89\xa0",  6, 6, TRUE },
+	/* some tests to check max_len handling */
+	/* length 1 */
+	{ "abcde", -1, 5, TRUE },
+	{ "abcde", 3, 3, TRUE },
+	{ "abcde", 5, 5, TRUE },
+	/* length 2 */
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9", -1, 6, TRUE },
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9",  1, 0, FALSE },
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9",  2, 2, TRUE },
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9",  3, 2, FALSE },
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9",  4, 4, TRUE },
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9",  5, 4, FALSE },
+	{ "\xc2\xa9\xc2\xa9\xc2\xa9",  6, 6, TRUE },
+	/* length 3 */
+	{ "\xe2\x89\xa0\xe2\x89\xa0", -1, 6, TRUE },
+	{ "\xe2\x89\xa0\xe2\x89\xa0",  1, 0, FALSE },
+	{ "\xe2\x89\xa0\xe2\x89\xa0",  2, 0, FALSE },
+	{ "\xe2\x89\xa0\xe2\x89\xa0",  3, 3, TRUE },
+	{ "\xe2\x89\xa0\xe2\x89\xa0",  4, 3, FALSE },
+	{ "\xe2\x89\xa0\xe2\x89\xa0",  5, 3, FALSE },
+	{ "\xe2\x89\xa0\xe2\x89\xa0",  6, 6, TRUE },
 
-  /* examples from https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
-  /* greek 'kosme' */
-  { "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
-  /* first sequence of each length */
-  { "\x00", -1, 0, TRUE },
-  { "\xc2\x80", -1, 2, TRUE },
-  { "\xe0\xa0\x80", -1, 3, TRUE },
-  { "\xf0\x90\x80\x80", -1, 4, TRUE },
-  { "\xf8\x88\x80\x80\x80", -1, 0, FALSE },
-  { "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE },
-  /* last sequence of each length */
-  { "\x7f", -1, 1, TRUE },
-  { "\xdf\xbf", -1, 2, TRUE },
-  { "\xef\xbf\xbf", -1, 0, TRUE },
-  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
-  { "\xf4\x90\xbf\xbf", -1, 0, FALSE },
-  { "\xf7\xbf\xbf\xbf", -1, 0, FALSE },
-  { "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE },
-  { "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE },
-  /* other boundary conditions */
-  { "\xed\x9f\xbf", -1, 3, TRUE },
-  { "\xed\xa0\x80", -1, 0, FALSE },
-  { "\xed\xbf\xbf", -1, 0, FALSE },
-  { "\xee\x80\x80", -1, 3, TRUE },
-  { "\xef\xbf\xbd", -1, 3, TRUE },
-  { "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
-  /* malformed sequences */
-  /* continuation bytes */
-  { "\x80", -1, 0, FALSE },
-  { "\xbf", -1, 0, FALSE },
-  { "\x80\xbf", -1, 0, FALSE },
-  { "\x80\xbf\x80", -1, 0, FALSE },
-  { "\x80\xbf\x80\xbf", -1, 0, FALSE },
-  { "\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
-  { "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE },
-  { "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
+	/* examples from https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt */
+	/* greek 'kosme' */
+	{ "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5", -1, 11, TRUE },
+	/* first sequence of each length */
+	{ "\x00", -1, 0, TRUE },
+	{ "\xc2\x80", -1, 2, TRUE },
+	{ "\xe0\xa0\x80", -1, 3, TRUE },
+	{ "\xf0\x90\x80\x80", -1, 4, TRUE },
+	{ "\xf8\x88\x80\x80\x80", -1, 0, FALSE },
+	{ "\xfc\x84\x80\x80\x80\x80", -1, 0, FALSE },
+	/* last sequence of each length */
+	{ "\x7f", -1, 1, TRUE },
+	{ "\xdf\xbf", -1, 2, TRUE },
+	{ "\xef\xbf\xbf", -1, 0, TRUE },
+	{ "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
+	{ "\xf4\x90\xbf\xbf", -1, 0, FALSE },
+	{ "\xf7\xbf\xbf\xbf", -1, 0, FALSE },
+	{ "\xfb\xbf\xbf\xbf\xbf", -1, 0, FALSE },
+	{ "\xfd\xbf\xbf\xbf\xbf\xbf", -1, 0, FALSE },
+	/* other boundary conditions */
+	{ "\xed\x9f\xbf", -1, 3, TRUE },
+	{ "\xed\xa0\x80", -1, 0, FALSE },
+	{ "\xed\xbf\xbf", -1, 0, FALSE },
+	{ "\xee\x80\x80", -1, 3, TRUE },
+	{ "\xef\xbf\xbd", -1, 3, TRUE },
+	{ "\xf4\x8f\xbf\xbf", -1, 0, TRUE },
+	/* malformed sequences */
+	/* continuation bytes */
+	{ "\x80", -1, 0, FALSE },
+	{ "\xbf", -1, 0, FALSE },
+	{ "\x80\xbf", -1, 0, FALSE },
+	{ "\x80\xbf\x80", -1, 0, FALSE },
+	{ "\x80\xbf\x80\xbf", -1, 0, FALSE },
+	{ "\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
+	{ "\x80\xbf\x80\xbf\x80\xbf", -1, 0, FALSE },
+	{ "\x80\xbf\x80\xbf\x80\xbf\x80", -1, 0, FALSE },
 
-  /* all possible continuation byte */
-  { "\x80", -1, 0, FALSE },
-  { "\x81", -1, 0, FALSE },
-  { "\x82", -1, 0, FALSE },
-  { "\x83", -1, 0, FALSE },
-  { "\x84", -1, 0, FALSE },
-  { "\x85", -1, 0, FALSE },
-  { "\x86", -1, 0, FALSE },
-  { "\x87", -1, 0, FALSE },
-  { "\x88", -1, 0, FALSE },
-  { "\x89", -1, 0, FALSE },
-  { "\x8a", -1, 0, FALSE },
-  { "\x8b", -1, 0, FALSE },
-  { "\x8c", -1, 0, FALSE },
-  { "\x8d", -1, 0, FALSE },
-  { "\x8e", -1, 0, FALSE },
-  { "\x8f", -1, 0, FALSE },
-  { "\x90", -1, 0, FALSE },
-  { "\x91", -1, 0, FALSE },
-  { "\x92", -1, 0, FALSE },
-  { "\x93", -1, 0, FALSE },
-  { "\x94", -1, 0, FALSE },
-  { "\x95", -1, 0, FALSE },
-  { "\x96", -1, 0, FALSE },
-  { "\x97", -1, 0, FALSE },
-  { "\x98", -1, 0, FALSE },
-  { "\x99", -1, 0, FALSE },
-  { "\x9a", -1, 0, FALSE },
-  { "\x9b", -1, 0, FALSE },
-  { "\x9c", -1, 0, FALSE },
-  { "\x9d", -1, 0, FALSE },
-  { "\x9e", -1, 0, FALSE },
-  { "\x9f", -1, 0, FALSE },
-  { "\xa0", -1, 0, FALSE },
-  { "\xa1", -1, 0, FALSE },
-  { "\xa2", -1, 0, FALSE },
-  { "\xa3", -1, 0, FALSE },
-  { "\xa4", -1, 0, FALSE },
-  { "\xa5", -1, 0, FALSE },
-  { "\xa6", -1, 0, FALSE },
-  { "\xa7", -1, 0, FALSE },
-  { "\xa8", -1, 0, FALSE },
-  { "\xa9", -1, 0, FALSE },
-  { "\xaa", -1, 0, FALSE },
-  { "\xab", -1, 0, FALSE },
-  { "\xac", -1, 0, FALSE },
-  { "\xad", -1, 0, FALSE },
-  { "\xae", -1, 0, FALSE },
-  { "\xaf", -1, 0, FALSE },
-  { "\xb0", -1, 0, FALSE },
-  { "\xb1", -1, 0, FALSE },
-  { "\xb2", -1, 0, FALSE },
-  { "\xb3", -1, 0, FALSE },
-  { "\xb4", -1, 0, FALSE },
-  { "\xb5", -1, 0, FALSE },
-  { "\xb6", -1, 0, FALSE },
-  { "\xb7", -1, 0, FALSE },
-  { "\xb8", -1, 0, FALSE },
-  { "\xb9", -1, 0, FALSE },
-  { "\xba", -1, 0, FALSE },
-  { "\xbb", -1, 0, FALSE },
-  { "\xbc", -1, 0, FALSE },
-  { "\xbd", -1, 0, FALSE },
-  { "\xbe", -1, 0, FALSE },
-  { "\xbf", -1, 0, FALSE },
-  /* lone start characters */
-  { "\xc0\x20", -1, 0, FALSE },
-  { "\xc1\x20", -1, 0, FALSE },
-  { "\xc2\x20", -1, 0, FALSE },
-  { "\xc3\x20", -1, 0, FALSE },
-  { "\xc4\x20", -1, 0, FALSE },
-  { "\xc5\x20", -1, 0, FALSE },
-  { "\xc6\x20", -1, 0, FALSE },
-  { "\xc7\x20", -1, 0, FALSE },
-  { "\xc8\x20", -1, 0, FALSE },
-  { "\xc9\x20", -1, 0, FALSE },
-  { "\xca\x20", -1, 0, FALSE },
-  { "\xcb\x20", -1, 0, FALSE },
-  { "\xcc\x20", -1, 0, FALSE },
-  { "\xcd\x20", -1, 0, FALSE },
-  { "\xce\x20", -1, 0, FALSE },
-  { "\xcf\x20", -1, 0, FALSE },
-  { "\xd0\x20", -1, 0, FALSE },
-  { "\xd1\x20", -1, 0, FALSE },
-  { "\xd2\x20", -1, 0, FALSE },
-  { "\xd3\x20", -1, 0, FALSE },
-  { "\xd4\x20", -1, 0, FALSE },
-  { "\xd5\x20", -1, 0, FALSE },
-  { "\xd6\x20", -1, 0, FALSE },
-  { "\xd7\x20", -1, 0, FALSE },
-  { "\xd8\x20", -1, 0, FALSE },
-  { "\xd9\x20", -1, 0, FALSE },
-  { "\xda\x20", -1, 0, FALSE },
-  { "\xdb\x20", -1, 0, FALSE },
-  { "\xdc\x20", -1, 0, FALSE },
-  { "\xdd\x20", -1, 0, FALSE },
-  { "\xde\x20", -1, 0, FALSE },
-  { "\xdf\x20", -1, 0, FALSE },
-  { "\xe0\x20", -1, 0, FALSE },
-  { "\xe1\x20", -1, 0, FALSE },
-  { "\xe2\x20", -1, 0, FALSE },
-  { "\xe3\x20", -1, 0, FALSE },
-  { "\xe4\x20", -1, 0, FALSE },
-  { "\xe5\x20", -1, 0, FALSE },
-  { "\xe6\x20", -1, 0, FALSE },
-  { "\xe7\x20", -1, 0, FALSE },
-  { "\xe8\x20", -1, 0, FALSE },
-  { "\xe9\x20", -1, 0, FALSE },
-  { "\xea\x20", -1, 0, FALSE },
-  { "\xeb\x20", -1, 0, FALSE },
-  { "\xec\x20", -1, 0, FALSE },
-  { "\xed\x20", -1, 0, FALSE },
-  { "\xee\x20", -1, 0, FALSE },
-  { "\xef\x20", -1, 0, FALSE },
-  { "\xf0\x20", -1, 0, FALSE },
-  { "\xf1\x20", -1, 0, FALSE },
-  { "\xf2\x20", -1, 0, FALSE },
-  { "\xf3\x20", -1, 0, FALSE },
-  { "\xf4\x20", -1, 0, FALSE },
-  { "\xf5\x20", -1, 0, FALSE },
-  { "\xf6\x20", -1, 0, FALSE },
-  { "\xf7\x20", -1, 0, FALSE },
-  { "\xf8\x20", -1, 0, FALSE },
-  { "\xf9\x20", -1, 0, FALSE },
-  { "\xfa\x20", -1, 0, FALSE },
-  { "\xfb\x20", -1, 0, FALSE },
-  { "\xfc\x20", -1, 0, FALSE },
-  { "\xfd\x20", -1, 0, FALSE },
-  /* missing continuation bytes */
-  { "\x20\xc0", -1, 1, FALSE },
-  { "\x20\xe0\x80", -1, 1, FALSE },
-  { "\x20\xf0\x80\x80", -1, 1, FALSE },
-  { "\x20\xf8\x80\x80\x80", -1, 1, FALSE },
-  { "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE },
-  { "\x20\xdf", -1, 1, FALSE },
-  { "\x20\xef\xbf", -1, 1, FALSE },
-  { "\x20\xf7\xbf\xbf", -1, 1, FALSE },
-  { "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE },
-  { "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE },
-  /* impossible bytes */
-  { "\x20\xfe\x20", -1, 1, FALSE },
-  { "\x20\xff\x20", -1, 1, FALSE },
-  /* overlong sequences */
-  { "\x20\xc0\xaf\x20", -1, 1, FALSE },
-  { "\x20\xe0\x80\xaf\x20", -1, 1, FALSE },
-  { "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE },
-  { "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE },
-  { "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE },
-  { "\x20\xc1\xbf\x20", -1, 1, FALSE },
-  { "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE },
-  { "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xc0\x80\x20", -1, 1, FALSE },
-  { "\x20\xe0\x80\x80\x20", -1, 1, FALSE },
-  { "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE },
-  { "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE },
-  { "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE },
-  /* illegal code positions */
-  { "\x20\xed\xa0\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xad\xbf\x20", -1, 1, FALSE },
-  { "\x20\xed\xae\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xaf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xed\xb0\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xbe\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
-  { "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
-  { "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
+	/* all possible continuation byte */
+	{ "\x80", -1, 0, FALSE },
+	{ "\x81", -1, 0, FALSE },
+	{ "\x82", -1, 0, FALSE },
+	{ "\x83", -1, 0, FALSE },
+	{ "\x84", -1, 0, FALSE },
+	{ "\x85", -1, 0, FALSE },
+	{ "\x86", -1, 0, FALSE },
+	{ "\x87", -1, 0, FALSE },
+	{ "\x88", -1, 0, FALSE },
+	{ "\x89", -1, 0, FALSE },
+	{ "\x8a", -1, 0, FALSE },
+	{ "\x8b", -1, 0, FALSE },
+	{ "\x8c", -1, 0, FALSE },
+	{ "\x8d", -1, 0, FALSE },
+	{ "\x8e", -1, 0, FALSE },
+	{ "\x8f", -1, 0, FALSE },
+	{ "\x90", -1, 0, FALSE },
+	{ "\x91", -1, 0, FALSE },
+	{ "\x92", -1, 0, FALSE },
+	{ "\x93", -1, 0, FALSE },
+	{ "\x94", -1, 0, FALSE },
+	{ "\x95", -1, 0, FALSE },
+	{ "\x96", -1, 0, FALSE },
+	{ "\x97", -1, 0, FALSE },
+	{ "\x98", -1, 0, FALSE },
+	{ "\x99", -1, 0, FALSE },
+	{ "\x9a", -1, 0, FALSE },
+	{ "\x9b", -1, 0, FALSE },
+	{ "\x9c", -1, 0, FALSE },
+	{ "\x9d", -1, 0, FALSE },
+	{ "\x9e", -1, 0, FALSE },
+	{ "\x9f", -1, 0, FALSE },
+	{ "\xa0", -1, 0, FALSE },
+	{ "\xa1", -1, 0, FALSE },
+	{ "\xa2", -1, 0, FALSE },
+	{ "\xa3", -1, 0, FALSE },
+	{ "\xa4", -1, 0, FALSE },
+	{ "\xa5", -1, 0, FALSE },
+	{ "\xa6", -1, 0, FALSE },
+	{ "\xa7", -1, 0, FALSE },
+	{ "\xa8", -1, 0, FALSE },
+	{ "\xa9", -1, 0, FALSE },
+	{ "\xaa", -1, 0, FALSE },
+	{ "\xab", -1, 0, FALSE },
+	{ "\xac", -1, 0, FALSE },
+	{ "\xad", -1, 0, FALSE },
+	{ "\xae", -1, 0, FALSE },
+	{ "\xaf", -1, 0, FALSE },
+	{ "\xb0", -1, 0, FALSE },
+	{ "\xb1", -1, 0, FALSE },
+	{ "\xb2", -1, 0, FALSE },
+	{ "\xb3", -1, 0, FALSE },
+	{ "\xb4", -1, 0, FALSE },
+	{ "\xb5", -1, 0, FALSE },
+	{ "\xb6", -1, 0, FALSE },
+	{ "\xb7", -1, 0, FALSE },
+	{ "\xb8", -1, 0, FALSE },
+	{ "\xb9", -1, 0, FALSE },
+	{ "\xba", -1, 0, FALSE },
+	{ "\xbb", -1, 0, FALSE },
+	{ "\xbc", -1, 0, FALSE },
+	{ "\xbd", -1, 0, FALSE },
+	{ "\xbe", -1, 0, FALSE },
+	{ "\xbf", -1, 0, FALSE },
+	/* lone start characters */
+	{ "\xc0\x20", -1, 0, FALSE },
+	{ "\xc1\x20", -1, 0, FALSE },
+	{ "\xc2\x20", -1, 0, FALSE },
+	{ "\xc3\x20", -1, 0, FALSE },
+	{ "\xc4\x20", -1, 0, FALSE },
+	{ "\xc5\x20", -1, 0, FALSE },
+	{ "\xc6\x20", -1, 0, FALSE },
+	{ "\xc7\x20", -1, 0, FALSE },
+	{ "\xc8\x20", -1, 0, FALSE },
+	{ "\xc9\x20", -1, 0, FALSE },
+	{ "\xca\x20", -1, 0, FALSE },
+	{ "\xcb\x20", -1, 0, FALSE },
+	{ "\xcc\x20", -1, 0, FALSE },
+	{ "\xcd\x20", -1, 0, FALSE },
+	{ "\xce\x20", -1, 0, FALSE },
+	{ "\xcf\x20", -1, 0, FALSE },
+	{ "\xd0\x20", -1, 0, FALSE },
+	{ "\xd1\x20", -1, 0, FALSE },
+	{ "\xd2\x20", -1, 0, FALSE },
+	{ "\xd3\x20", -1, 0, FALSE },
+	{ "\xd4\x20", -1, 0, FALSE },
+	{ "\xd5\x20", -1, 0, FALSE },
+	{ "\xd6\x20", -1, 0, FALSE },
+	{ "\xd7\x20", -1, 0, FALSE },
+	{ "\xd8\x20", -1, 0, FALSE },
+	{ "\xd9\x20", -1, 0, FALSE },
+	{ "\xda\x20", -1, 0, FALSE },
+	{ "\xdb\x20", -1, 0, FALSE },
+	{ "\xdc\x20", -1, 0, FALSE },
+	{ "\xdd\x20", -1, 0, FALSE },
+	{ "\xde\x20", -1, 0, FALSE },
+	{ "\xdf\x20", -1, 0, FALSE },
+	{ "\xe0\x20", -1, 0, FALSE },
+	{ "\xe1\x20", -1, 0, FALSE },
+	{ "\xe2\x20", -1, 0, FALSE },
+	{ "\xe3\x20", -1, 0, FALSE },
+	{ "\xe4\x20", -1, 0, FALSE },
+	{ "\xe5\x20", -1, 0, FALSE },
+	{ "\xe6\x20", -1, 0, FALSE },
+	{ "\xe7\x20", -1, 0, FALSE },
+	{ "\xe8\x20", -1, 0, FALSE },
+	{ "\xe9\x20", -1, 0, FALSE },
+	{ "\xea\x20", -1, 0, FALSE },
+	{ "\xeb\x20", -1, 0, FALSE },
+	{ "\xec\x20", -1, 0, FALSE },
+	{ "\xed\x20", -1, 0, FALSE },
+	{ "\xee\x20", -1, 0, FALSE },
+	{ "\xef\x20", -1, 0, FALSE },
+	{ "\xf0\x20", -1, 0, FALSE },
+	{ "\xf1\x20", -1, 0, FALSE },
+	{ "\xf2\x20", -1, 0, FALSE },
+	{ "\xf3\x20", -1, 0, FALSE },
+	{ "\xf4\x20", -1, 0, FALSE },
+	{ "\xf5\x20", -1, 0, FALSE },
+	{ "\xf6\x20", -1, 0, FALSE },
+	{ "\xf7\x20", -1, 0, FALSE },
+	{ "\xf8\x20", -1, 0, FALSE },
+	{ "\xf9\x20", -1, 0, FALSE },
+	{ "\xfa\x20", -1, 0, FALSE },
+	{ "\xfb\x20", -1, 0, FALSE },
+	{ "\xfc\x20", -1, 0, FALSE },
+	{ "\xfd\x20", -1, 0, FALSE },
+	/* missing continuation bytes */
+	{ "\x20\xc0", -1, 1, FALSE },
+	{ "\x20\xe0\x80", -1, 1, FALSE },
+	{ "\x20\xf0\x80\x80", -1, 1, FALSE },
+	{ "\x20\xf8\x80\x80\x80", -1, 1, FALSE },
+	{ "\x20\xfc\x80\x80\x80\x80", -1, 1, FALSE },
+	{ "\x20\xdf", -1, 1, FALSE },
+	{ "\x20\xef\xbf", -1, 1, FALSE },
+	{ "\x20\xf7\xbf\xbf", -1, 1, FALSE },
+	{ "\x20\xfb\xbf\xbf\xbf", -1, 1, FALSE },
+	{ "\x20\xfd\xbf\xbf\xbf\xbf", -1, 1, FALSE },
+	/* impossible bytes */
+	{ "\x20\xfe\x20", -1, 1, FALSE },
+	{ "\x20\xff\x20", -1, 1, FALSE },
+	/* overlong sequences */
+	{ "\x20\xc0\xaf\x20", -1, 1, FALSE },
+	{ "\x20\xe0\x80\xaf\x20", -1, 1, FALSE },
+	{ "\x20\xf0\x80\x80\xaf\x20", -1, 1, FALSE },
+	{ "\x20\xf8\x80\x80\x80\xaf\x20", -1, 1, FALSE },
+	{ "\x20\xfc\x80\x80\x80\x80\xaf\x20", -1, 1, FALSE },
+	{ "\x20\xc1\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xe0\x9f\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xf0\x8f\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xf8\x87\xbf\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xfc\x83\xbf\xbf\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xc0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xe0\x80\x80\x20", -1, 1, FALSE },
+	{ "\x20\xf0\x80\x80\x80\x20", -1, 1, FALSE },
+	{ "\x20\xf8\x80\x80\x80\x80\x20", -1, 1, FALSE },
+	{ "\x20\xfc\x80\x80\x80\x80\x80\x20", -1, 1, FALSE },
+	/* illegal code positions */
+	{ "\x20\xed\xa0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xad\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xed\xae\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xaf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xed\xb0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xbe\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xed\xa0\x80\xed\xb0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xa0\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xed\xad\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xad\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xed\xae\x80\xed\xb0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xae\x80\xed\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xed\xaf\xbf\xed\xb0\x80\x20", -1, 1, FALSE },
+	{ "\x20\xed\xaf\xbf\xed\xbf\xbf\x20", -1, 1, FALSE },
 #if 0 /* We don't consider U+FFFE / U+FFFF and similar invalid. */
-  { "\x20\xef\xbf\xbe\x20", -1, 1, FALSE },
-  { "\x20\xef\xbf\xbf\x20", -1, 1, FALSE },
+	{ "\x20\xef\xbf\xbe\x20", -1, 1, FALSE },
+	{ "\x20\xef\xbf\xbf\x20", -1, 1, FALSE },
 #endif
-  { "", -1, 0, TRUE }
+	{ "", -1, 0, TRUE }
 };
 
 static void
 test_buffer_utf8_validity (void)
 {
-  hb_buffer_t *b;
-  unsigned int i;
+	hb_buffer_t *b;
+	unsigned int i;
 
-  b = hb_buffer_create ();
-  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
+	b = hb_buffer_create ();
+	hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
 
-  for (i = 0; i < G_N_ELEMENTS (utf8_validity_tests); i++)
-  {
-    const utf8_validity_test_t *test = &utf8_validity_tests[i];
-    unsigned int text_bytes, segment_bytes, j, len;
-    hb_glyph_info_t *glyphs;
-    char *escaped;
+	for (i = 0; i < G_N_ELEMENTS (utf8_validity_tests); i++)
+	{
+		const utf8_validity_test_t *test = &utf8_validity_tests[i];
+		unsigned int text_bytes, segment_bytes, j, len;
+		hb_glyph_info_t *glyphs;
+		char *escaped;
 
-    escaped = g_strescape (test->utf8, NULL);
-    g_test_message ("UTF-8 test #%d: %s", i, escaped);
-    g_free (escaped);
+		escaped = g_strescape (test->utf8, NULL);
+		g_test_message ("UTF-8 test #%d: %s", i, escaped);
+		g_free (escaped);
 
-    text_bytes = strlen (test->utf8);
-    if (test->max_len == -1)
-      segment_bytes = text_bytes;
-    else
-      segment_bytes = test->max_len;
+		text_bytes = strlen (test->utf8);
+		if (test->max_len == -1)
+			segment_bytes = text_bytes;
+		else
+			segment_bytes = test->max_len;
 
-    hb_buffer_clear_contents (b);
-    hb_buffer_add_utf8 (b, test->utf8, text_bytes,  0, segment_bytes);
+		hb_buffer_clear_contents (b);
+		hb_buffer_add_utf8 (b, test->utf8, text_bytes,  0, segment_bytes);
 
-    glyphs = hb_buffer_get_glyph_infos (b, &len);
-    for (j = 0; j < len; j++)
-      if (glyphs[j].codepoint == (hb_codepoint_t) -1)
+		glyphs = hb_buffer_get_glyph_infos (b, &len);
+		for (j = 0; j < len; j++)
+			if (glyphs[j].codepoint == (hb_codepoint_t) -1)
 	break;
 
-    g_assert (test->valid ? j == len : j < len);
-    if (!test->valid)
-      g_assert (glyphs[j].cluster == test->offset);
-  }
+		g_assert (test->valid ? j == len : j < len);
+		if (!test->valid)
+			g_assert (glyphs[j].cluster == test->offset);
+	}
 
-  hb_buffer_destroy (b);
+	hb_buffer_destroy (b);
 }
 
 
 typedef struct {
-  const uint16_t utf16[8];
-  const uint32_t codepoints[8];
+	const uint16_t utf16[8];
+	const uint32_t codepoints[8];
 } utf16_conversion_test_t;
 
 /* note: we skip the first and last item from utf16 when adding to buffer */
 static const utf16_conversion_test_t utf16_conversion_tests[] = {
-  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
-  {{0x41, 0xD800, 0xDF02, 0x61}, {0x10302}},
-  {{0x41, 0xD800, 0xDF02}, {(hb_codepoint_t) -1}},
-  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, (hb_codepoint_t) -1}},
-  {{0x41, 0xD800, 0x61, 0xDF02}, {(hb_codepoint_t) -1, 0x61}},
-  {{0x41, 0xDF00, 0x61}, {(hb_codepoint_t) -1}},
-  {{0x41, 0x61}, {0}}
+	{{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
+	{{0x41, 0xD800, 0xDF02, 0x61}, {0x10302}},
+	{{0x41, 0xD800, 0xDF02}, {(hb_codepoint_t) -1}},
+	{{0x41, 0x61, 0xD800, 0xDF02}, {0x61, (hb_codepoint_t) -1}},
+	{{0x41, 0xD800, 0x61, 0xDF02}, {(hb_codepoint_t) -1, 0x61}},
+	{{0x41, 0xDF00, 0x61}, {(hb_codepoint_t) -1}},
+	{{0x41, 0x61}, {0}}
 };
 
 static void
 test_buffer_utf16_conversion (void)
 {
-  hb_buffer_t *b;
-  unsigned int i;
+	hb_buffer_t *b;
+	unsigned int i;
 
-  b = hb_buffer_create ();
-  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
+	b = hb_buffer_create ();
+	hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
 
-  for (i = 0; i < G_N_ELEMENTS (utf16_conversion_tests); i++)
-  {
-    const utf16_conversion_test_t *test = &utf16_conversion_tests[i];
-    unsigned int u_len, chars, j, len;
-    hb_glyph_info_t *glyphs;
+	for (i = 0; i < G_N_ELEMENTS (utf16_conversion_tests); i++)
+	{
+		const utf16_conversion_test_t *test = &utf16_conversion_tests[i];
+		unsigned int u_len, chars, j, len;
+		hb_glyph_info_t *glyphs;
 
-    g_test_message ("UTF-16 test #%d", i);
+		g_test_message ("UTF-16 test #%d", i);
 
-    for (u_len = 0; test->utf16[u_len]; u_len++)
-      ;
-    for (chars = 0; test->codepoints[chars]; chars++)
-      ;
+		for (u_len = 0; test->utf16[u_len]; u_len++)
+			;
+		for (chars = 0; test->codepoints[chars]; chars++)
+			;
 
-    hb_buffer_clear_contents (b);
-    hb_buffer_add_utf16 (b, test->utf16, u_len,  1, u_len - 2);
+		hb_buffer_clear_contents (b);
+		hb_buffer_add_utf16 (b, test->utf16, u_len,  1, u_len - 2);
 
-    glyphs = hb_buffer_get_glyph_infos (b, &len);
-    g_assert_cmpint (len, ==, chars);
-    for (j = 0; j < chars; j++)
-      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
-  }
+		glyphs = hb_buffer_get_glyph_infos (b, &len);
+		g_assert_cmpint (len, ==, chars);
+		for (j = 0; j < chars; j++)
+			g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
+	}
 
-  hb_buffer_destroy (b);
+	hb_buffer_destroy (b);
 }
 
 
 typedef struct {
-  const uint32_t utf32[8];
-  const uint32_t codepoints[8];
+	const uint32_t utf32[8];
+	const uint32_t codepoints[8];
 } utf32_conversion_test_t;
 
 /* note: we skip the first and last item from utf32 when adding to buffer */
 static const utf32_conversion_test_t utf32_conversion_tests[] = {
-  {{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, (hb_codepoint_t) -3, (hb_codepoint_t) -3}},
-  {{0x41, 0x004D, 0x0430, 0x4E8C, 0x10302, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
-  {{0x41, 0xD800, 0xDF02, 0x61}, {(hb_codepoint_t) -3, (hb_codepoint_t) -3}},
-  {{0x41, 0xD800, 0xDF02}, {(hb_codepoint_t) -3}},
-  {{0x41, 0x61, 0xD800, 0xDF02}, {0x61, (hb_codepoint_t) -3}},
-  {{0x41, 0xD800, 0x61, 0xDF02}, {(hb_codepoint_t) -3, 0x61}},
-  {{0x41, 0xDF00, 0x61}, {(hb_codepoint_t) -3}},
-  {{0x41, 0x10FFFF, 0x61}, {0x10FFFF}},
-  {{0x41, 0x110000, 0x61}, {(hb_codepoint_t) -3}},
-  {{0x41, 0x61}, {0}}
+	{{0x41, 0x004D, 0x0430, 0x4E8C, 0xD800, 0xDF02, 0x61} , {0x004D, 0x0430, 0x4E8C, (hb_codepoint_t) -3, (hb_codepoint_t) -3}},
+	{{0x41, 0x004D, 0x0430, 0x4E8C, 0x10302, 0x61} , {0x004D, 0x0430, 0x4E8C, 0x10302}},
+	{{0x41, 0xD800, 0xDF02, 0x61}, {(hb_codepoint_t) -3, (hb_codepoint_t) -3}},
+	{{0x41, 0xD800, 0xDF02}, {(hb_codepoint_t) -3}},
+	{{0x41, 0x61, 0xD800, 0xDF02}, {0x61, (hb_codepoint_t) -3}},
+	{{0x41, 0xD800, 0x61, 0xDF02}, {(hb_codepoint_t) -3, 0x61}},
+	{{0x41, 0xDF00, 0x61}, {(hb_codepoint_t) -3}},
+	{{0x41, 0x10FFFF, 0x61}, {0x10FFFF}},
+	{{0x41, 0x110000, 0x61}, {(hb_codepoint_t) -3}},
+	{{0x41, 0x61}, {0}}
 };
 
 static void
 test_buffer_utf32_conversion (void)
 {
-  hb_buffer_t *b;
-  unsigned int i;
+	hb_buffer_t *b;
+	unsigned int i;
 
-  b = hb_buffer_create ();
-  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -3);
+	b = hb_buffer_create ();
+	hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -3);
 
-  for (i = 0; i < G_N_ELEMENTS (utf32_conversion_tests); i++)
-  {
-    const utf32_conversion_test_t *test = &utf32_conversion_tests[i];
-    unsigned int u_len, chars, j, len;
-    hb_glyph_info_t *glyphs;
+	for (i = 0; i < G_N_ELEMENTS (utf32_conversion_tests); i++)
+	{
+		const utf32_conversion_test_t *test = &utf32_conversion_tests[i];
+		unsigned int u_len, chars, j, len;
+		hb_glyph_info_t *glyphs;
 
-    g_test_message ("UTF-32 test #%d", i);
+		g_test_message ("UTF-32 test #%d", i);
 
-    for (u_len = 0; test->utf32[u_len]; u_len++)
-      ;
-    for (chars = 0; test->codepoints[chars]; chars++)
-      ;
+		for (u_len = 0; test->utf32[u_len]; u_len++)
+			;
+		for (chars = 0; test->codepoints[chars]; chars++)
+			;
 
-    hb_buffer_clear_contents (b);
-    hb_buffer_add_utf32 (b, test->utf32, u_len,  1, u_len - 2);
+		hb_buffer_clear_contents (b);
+		hb_buffer_add_utf32 (b, test->utf32, u_len,  1, u_len - 2);
 
-    glyphs = hb_buffer_get_glyph_infos (b, &len);
-    g_assert_cmpint (len, ==, chars);
-    for (j = 0; j < chars; j++)
-      g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
-  }
+		glyphs = hb_buffer_get_glyph_infos (b, &len);
+		g_assert_cmpint (len, ==, chars);
+		for (j = 0; j < chars; j++)
+			g_assert_cmphex (glyphs[j].codepoint, ==, test->codepoints[j]);
+	}
 
-  hb_buffer_destroy (b);
+	hb_buffer_destroy (b);
 }
 
 
 static void
 test_empty (hb_buffer_t *b)
 {
-  g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
-  g_assert (!hb_buffer_get_glyph_infos (b, NULL));
-  g_assert (!hb_buffer_get_glyph_positions (b, NULL));
+	g_assert_cmpint (hb_buffer_get_length (b), ==, 0);
+	g_assert (!hb_buffer_get_glyph_infos (b, NULL));
+	g_assert (!hb_buffer_get_glyph_positions (b, NULL));
 }
 
 static void
 test_buffer_empty (void)
 {
-  hb_buffer_t *b = hb_buffer_get_empty ();
+	hb_buffer_t *b = hb_buffer_get_empty ();
 
-  g_assert (hb_buffer_get_empty ());
-  g_assert (hb_buffer_get_empty () == b);
+	g_assert (hb_buffer_get_empty ());
+	g_assert (hb_buffer_get_empty () == b);
 
-  g_assert (!hb_buffer_allocation_successful (b));
+	g_assert (!hb_buffer_allocation_successful (b));
 
-  test_empty (b);
+	test_empty (b);
 
-  hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
+	hb_buffer_add_utf32 (b, utf32, G_N_ELEMENTS (utf32), 1, G_N_ELEMENTS (utf32) - 2);
 
-  test_empty (b);
+	test_empty (b);
 
-  hb_buffer_reverse (b);
-  hb_buffer_reverse_clusters (b);
+	hb_buffer_reverse (b);
+	hb_buffer_reverse_clusters (b);
 
-  g_assert (!hb_buffer_set_length (b, 10));
+	g_assert (!hb_buffer_set_length (b, 10));
 
-  test_empty (b);
+	test_empty (b);
 
-  g_assert (hb_buffer_set_length (b, 0));
+	g_assert (hb_buffer_set_length (b, 0));
 
-  test_empty (b);
+	test_empty (b);
 
-  g_assert (!hb_buffer_allocation_successful (b));
+	g_assert (!hb_buffer_allocation_successful (b));
 
-  hb_buffer_reset (b);
+	hb_buffer_reset (b);
 
-  test_empty (b);
+	test_empty (b);
 
-  g_assert (!hb_buffer_allocation_successful (b));
+	g_assert (!hb_buffer_allocation_successful (b));
 }
 
 typedef struct {
-  const char *contents;
-  hb_buffer_serialize_format_t format;
-  unsigned int num_items;
+	const char *contents;
+	hb_buffer_serialize_format_t format;
+	unsigned int num_items;
+	hb_bool_t success;
 } serialization_test_t;
 
 static const serialization_test_t serialization_tests[] = {
-  { "<U+0640=0|U+0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 2 },
-  { "[{\"u\":1600,\"cl\":0},{\"u\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 2 },
+	{ "<U+0640=0|U+0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 2, 1 },
+	{ "[{\"u\":1600,\"cl\":0},{\"u\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 2, 1 },
+
+	/* Mixed glyphs/Unicodes -> parse fail */
+	{ "[{\"u\":1600,\"cl\":0},{\"g\":1589,\"cl\":1}]", HB_BUFFER_SERIALIZE_FORMAT_JSON, 0, 0 },
+	{ "<U+0640=0|uni0635=1>", HB_BUFFER_SERIALIZE_FORMAT_TEXT, 0, 0 },
 };
 
 static void
 test_buffer_serialize_deserialize (void)
 {
-  hb_buffer_t *b;
-  unsigned int i;
+	hb_buffer_t *b;
+	unsigned int i;
 
-  for (i = 0; i < G_N_ELEMENTS (serialization_tests); i++)
-  {
-    unsigned int num_glyphs, consumed;
-    char round_trip[1024];
+	for (i = 0; i < G_N_ELEMENTS (serialization_tests); i++)
+	{
+		unsigned int num_glyphs, consumed;
+		char round_trip[1024];
+		hb_bool_t retval;
 
-	  b = hb_buffer_create ();
-	  hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
+		b = hb_buffer_create ();
+		hb_buffer_set_replacement_codepoint (b, (hb_codepoint_t) -1);
 
-    const serialization_test_t *test = &serialization_tests[i];
-    g_test_message ("serialize test #%d", i);
+		const serialization_test_t *test = &serialization_tests[i];
+		g_test_message ("serialize test #%d", i);
 
-    hb_buffer_deserialize_unicode (b, test->contents, -1, NULL, test->format);
+		retval = hb_buffer_deserialize_unicode (b, test->contents, -1, NULL, test->format);
 
-    num_glyphs = hb_buffer_get_length (b);
-    g_assert_cmpint (num_glyphs, ==, test->num_items);
+		if (test->success == 0)
+			continue; // Expected parse failure, got one, don't round-trip
 
-    hb_buffer_serialize_unicode(b, 0, num_glyphs, round_trip,
-                                sizeof(round_trip), &consumed, test->format,
-                                HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
-    g_assert_cmpstr (round_trip, ==, test->contents);
+		num_glyphs = hb_buffer_get_length (b);
+		g_assert_cmpint (num_glyphs, ==, test->num_items);
 
-	  hb_buffer_destroy (b);
+		hb_buffer_serialize_unicode(b, 0, num_glyphs, round_trip,
+																sizeof(round_trip), &consumed, test->format,
+																HB_BUFFER_SERIALIZE_FLAG_DEFAULT);
+		g_assert_cmpstr (round_trip, ==, test->contents);
 
-  }
+		hb_buffer_destroy (b);
+
+	}
 }
 
 int
 main (int argc, char **argv)
 {
-  unsigned int i;
+	unsigned int i;
 
-  hb_test_init (&argc, &argv);
+	hb_test_init (&argc, &argv);
 
-  for (i = 0; i < BUFFER_NUM_TYPES; i++)
-  {
-    const void *buffer_type = GINT_TO_POINTER (i);
-    const char *buffer_name = buffer_names[i];
+	for (i = 0; i < BUFFER_NUM_TYPES; i++)
+	{
+		const void *buffer_type = GINT_TO_POINTER (i);
+		const char *buffer_name = buffer_names[i];
 
-    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties);
-    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents);
-    hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions);
-  }
+		hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_properties);
+		hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_contents);
+		hb_test_add_fixture_flavor (fixture, buffer_type, buffer_name, test_buffer_positions);
+	}
 
-  hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation);
+	hb_test_add_fixture (fixture, GINT_TO_POINTER (BUFFER_EMPTY), test_buffer_allocation);
 
-  hb_test_add (test_buffer_utf8_conversion);
-  hb_test_add (test_buffer_utf8_validity);
-  hb_test_add (test_buffer_utf16_conversion);
-  hb_test_add (test_buffer_utf32_conversion);
-  hb_test_add (test_buffer_empty);
-  hb_test_add (test_buffer_serialize_deserialize);
+	hb_test_add (test_buffer_utf8_conversion);
+	hb_test_add (test_buffer_utf8_validity);
+	hb_test_add (test_buffer_utf16_conversion);
+	hb_test_add (test_buffer_utf32_conversion);
+	hb_test_add (test_buffer_empty);
+	hb_test_add (test_buffer_serialize_deserialize);
 
-  return hb_test_run();
+	return hb_test_run();
 }