diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
index 10076b7..a987f3b 100644
--- a/include/qapi/qmp/qstring.h
+++ b/include/qapi/qmp/qstring.h
@@ -1,7 +1,7 @@
 /*
  * QString Module
  *
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009-2016 Red Hat Inc.
  *
  * Authors:
  *  Luiz Capitulino <lcapitulino@redhat.com>
@@ -27,9 +27,12 @@ QString *qstring_from_str(const char *str);
 QString *qstring_from_substr(const char *str, int start, int end);
 size_t qstring_get_length(const QString *qstring);
 const char *qstring_get_str(const QString *qstring);
-void qstring_append_int(QString *qstring, int64_t value);
 void qstring_append(QString *qstring, const char *str);
 void qstring_append_chr(QString *qstring, int c);
+void qstring_append_printf(QString *qstring, const char *fmt, ...)
+    GCC_FMT_ATTR(2, 3);
+void qstring_append_vprintf(QString *qstring, const char *fmt, va_list ap)
+    GCC_FMT_ATTR(2, 0);
 QString *qobject_to_qstring(const QObject *obj);
 void qstring_destroy_obj(QObject *obj);

diff --git a/migration/qjson.c b/migration/qjson.c
index 741f9e6..f11effd 100644
--- a/migration/qjson.c
+++ b/migration/qjson.c
@@ -77,7 +77,7 @@ void json_end_array(QJSON *json)
 void json_prop_int(QJSON *json, const char *name, int64_t val)
 {
     json_emit_element(json, name);
-    qstring_append_int(json->str, val);
+    qstring_append_printf(json->str, "%" PRId64, val);
 }

 void json_prop_str(QJSON *json, const char *name, const char *str)
diff --git a/qobject/qjson.c b/qobject/qjson.c
index b47a361..7dc694c 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -82,16 +82,13 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent);
 static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
 {
     ToJsonIterState *s = opaque;
-    int j;

     if (s->count) {
         qstring_append(s->str, s->pretty ? "," : ", ");
     }

     if (s->pretty) {
-        qstring_append(s->str, "\n");
-        for (j = 0 ; j < s->indent ; j++)
-            qstring_append(s->str, "    ");
+        qstring_append_printf(s->str, "\n%*s", 4 * s->indent, "");
     }

     qstring_append_json_string(s->str, key);
@@ -104,16 +101,13 @@ static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
 static void to_json_list_iter(QObject *obj, void *opaque)
 {
     ToJsonIterState *s = opaque;
-    int j;

     if (s->count) {
         qstring_append(s->str, s->pretty ? "," : ", ");
     }

     if (s->pretty) {
-        qstring_append(s->str, "\n");
-        for (j = 0 ; j < s->indent ; j++)
-            qstring_append(s->str, "    ");
+        qstring_append_printf(s->str, "\n%*s", 4 * s->indent, "");
     }

     to_json(obj, s->str, s->pretty, s->indent);
@@ -128,10 +122,7 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
         break;
     case QTYPE_QINT: {
         QInt *val = qobject_to_qint(obj);
-        char buffer[1024];
-
-        snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val));
-        qstring_append(str, buffer);
+        qstring_append_printf(str, "%" PRId64, qint_get_int(val));
         break;
     }
     case QTYPE_QSTRING: {
@@ -152,10 +143,7 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
         qstring_append(str, "{");
         qdict_iter(val, to_json_dict_iter, &s);
         if (pretty) {
-            int j;
-            qstring_append(str, "\n");
-            for (j = 0 ; j < indent ; j++)
-                qstring_append(str, "    ");
+            qstring_append_printf(str, "\n%*s", 4 * indent, "");
         }
         qstring_append(str, "}");
         break;
@@ -171,10 +159,7 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent)
         qstring_append(str, "[");
         qlist_iter(val, (void *)to_json_list_iter, &s);
         if (pretty) {
-            int j;
-            qstring_append(str, "\n");
-            for (j = 0 ; j < indent ; j++)
-                qstring_append(str, "    ");
+            qstring_append_printf(str, "\n%*s", 4 * indent, "");
         }
         qstring_append(str, "]");
         break;
@@ -230,7 +215,6 @@ int qstring_append_json_string(QString *qstring, const char *str)
 {
     const char *ptr;
     int cp;
-    char buf[16];
     char *end;
     int result = 0;

@@ -267,16 +251,14 @@ int qstring_append_json_string(QString *qstring, const char *str)
             }
             if (cp > 0xFFFF) {
                 /* beyond BMP; need a surrogate pair */
-                snprintf(buf, sizeof(buf), "\\u%04X\\u%04X",
-                         0xD800 + ((cp - 0x10000) >> 10),
-                         0xDC00 + ((cp - 0x10000) & 0x3FF));
+                qstring_append_printf(qstring, "\\u%04X\\u%04X",
+                                      0xD800 + ((cp - 0x10000) >> 10),
+                                      0xDc00 + ((cp - 0x10000) & 0x3FF));
             } else if (cp < 0x20 || cp >= 0x7F) {
-                snprintf(buf, sizeof(buf), "\\u%04X", cp);
+                qstring_append_printf(qstring, "\\u%04X", cp);
             } else {
-                buf[0] = cp;
-                buf[1] = 0;
+                qstring_append_chr(qstring, cp);
             }
-            qstring_append(qstring, buf);
         }
     };

diff --git a/qobject/qstring.c b/qobject/qstring.c
index 5da7b5f..fbfae27 100644
--- a/qobject/qstring.c
+++ b/qobject/qstring.c
@@ -1,7 +1,7 @@
 /*
  * QString Module
  *
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009-2016 Red Hat Inc.
  *
  * Authors:
  *  Luiz Capitulino <lcapitulino@redhat.com>
@@ -88,12 +88,28 @@ void qstring_append(QString *qstring, const char *str)
     qstring->string[qstring->length] = 0;
 }

-void qstring_append_int(QString *qstring, int64_t value)
+void qstring_append_printf(QString *qstring, const char *fmt, ...)
 {
-    char num[32];
+    va_list ap;

-    snprintf(num, sizeof(num), "%" PRId64, value);
-    qstring_append(qstring, num);
+    va_start(ap, fmt);
+    qstring_append_vprintf(qstring, fmt, ap);
+    va_end(ap);
+}
+
+void qstring_append_vprintf(QString *qstring, const char *fmt, va_list ap)
+{
+    va_list ap2;
+    int len;
+
+    va_copy(ap2, ap);
+    len = vsnprintf(NULL, 0, fmt, ap2);
+    assert(len >= 0);
+    va_end(ap2);
+
+    capacity_increase(qstring, len);
+    vsnprintf(qstring->string + qstring->length, len + 1, fmt, ap);
+    qstring->length += len;
 }

 /**
