Fixed "NULL + 0" UB in JSON encoder and decoder.
diff --git a/upb/json_encode.c b/upb/json_encode.c
index d118c9b..9963008 100644
--- a/upb/json_encode.c
+++ b/upb/json_encode.c
@@ -35,6 +35,11 @@
                               const upb_msgdef *m, bool first);
 static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
 
+static char *jsonenc_ptradd(char *ptr, size_t size) {
+  // Generates the same code as "ptr + size" but avoids UB of NULL + 0.
+  return size ? ptr + size : ptr;
+}
+
 UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) {
   upb_status_seterrmsg(e->status, msg);
   longjmp(e->err, 1);
@@ -63,8 +68,10 @@
     memcpy(e->ptr, data, len);
     e->ptr += len;
   } else {
-    if (have) memcpy(e->ptr, data, have);
-    e->ptr += have;
+    if (have) {
+      memcpy(e->ptr, data, have);
+      e->ptr += have;
+    }
     e->overflow += (len - have);
   }
 }
@@ -86,7 +93,7 @@
   if (UPB_LIKELY(have > n)) {
     e->ptr += n;
   } else {
-    e->ptr += have;
+    if (have) e->ptr += have;
     e->overflow += (n - have);
   }
 }
@@ -190,7 +197,7 @@
   static const char base64[] =
       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
   const unsigned char *ptr = (unsigned char*)str.data;
-  const unsigned char *end = ptr + str.size;
+  const unsigned char *end = jsonenc_ptradd(ptr, str.size);
   char buf[4];
 
   jsonenc_putstr(e, "\"");
@@ -226,7 +233,7 @@
 
 static void jsonenc_stringbody(jsonenc *e, upb_strview str) {
   const char *ptr = str.data;
-  const char *end = ptr + str.size;
+  const char *end = jsonenc_ptradd(ptr, str.size);
 
   while (ptr < end) {
     switch (*ptr) {
@@ -698,7 +705,7 @@
 
   e.buf = buf;
   e.ptr = buf;
-  e.end = buf + size;
+  e.end = jsonenc_ptradd(buf, size);
   e.overflow = 0;
   e.options = options;
   e.ext_pool = ext_pool;