diff --git a/src/vteconv.c b/src/vteconv.c
index ef94880..bed5c15 100644
--- a/src/vteconv.c
+++ b/src/vteconv.c
@@ -54,6 +54,53 @@ _vte_conv_utf8_strlen(const gchar *p, gssize max)
 	return length;
 }
 
+/* A variant of g_utf8_validate() that allows NUL characters.
+ * This is to address bug 730220.
+ * Requires that max_len >= 0 && end != NULL. */
+static gboolean
+_vte_utf8_validate (const gchar *str,
+                    gssize max_len,
+                    const gchar **end)
+{
+        gboolean ret;
+        do {
+                ret = g_utf8_validate(str, max_len, end);
+                max_len -= *end - str;
+                str = *end;
+                /* Hitting a NUL is okay. Clear the error and iterate over them. */
+                while (max_len > 0 && *str == '\0') {
+                        ret = TRUE;
+                        max_len--;
+                        str++;
+                        *end = str;
+                }
+        } while (ret && max_len > 0);
+        return ret;
+}
+
+/* A variant of g_utf8_get_char_validated() that allows NUL characters.
+ * This is to address bug 730220.
+ * Requires that max_len >= 0. */
+static gunichar
+_vte_utf8_get_char_validated (const gchar *p,
+                              gssize max_len) {
+        gunichar ret;
+        /* Handle NUL at the beginning. */
+        if (max_len > 0 && p[0] == '\0')
+                return 0;
+        ret = g_utf8_get_char_validated(p, max_len);
+        /* If okay or hopelessly broken, return that. */
+        if (ret != (gunichar) -2)
+                return ret;
+        /* Partial match. Bail out if there's a NUL in the input.
+         * g_utf8_get_char_validated() might have mistaken that for partial match,
+         * but it's actually an invalid sequence. */
+        else if (memchr(p, '\0', max_len) != NULL)
+                return (gunichar) -1;
+        else
+                return ret;
+}
+
 /* A bogus UTF-8 to UTF-8 conversion function which attempts to provide the
  * same semantics as g_iconv(). */
 static size_t
@@ -71,7 +118,7 @@ _vte_conv_utf8_utf8(GIConv converter,
 	g_assert(*outbytes_left >= *inbytes_left);
 
 	/* The only error we can throw is EILSEQ, so check for that here. */
-	validated = g_utf8_validate(*inbuf, *inbytes_left, &endptr);
+	validated = _vte_utf8_validate(*inbuf, *inbytes_left, &endptr);
 
 	/* Copy whatever data was validated. */
 	bytes = endptr - *inbuf;
@@ -88,7 +135,7 @@ _vte_conv_utf8_utf8(GIConv converter,
 	}
 
 	/* Determine why the end of the string is not valid. */
-	if (g_utf8_get_char_validated(*inbuf, *inbytes_left) == (gunichar) -2) {
+	if (_vte_utf8_get_char_validated(*inbuf, *inbytes_left) == (gunichar) -2) {
 		/* Prefix of a valid UTF-8 */
 		errno = EINVAL;
 	} else {
