D634: encoding: check overflow while calculating size of JSON escape buffer

singhsrb (Saurabh Singh) phabricator at mercurial-scm.org
Wed Sep 6 00:38:59 UTC 2017


singhsrb created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The minimum input size to exploit is ~682MB (= INT_MAX / len('\\u0000') * 2)
  on 32bit system, which isn't easy to achieve using Python str in 2GB process
  address space, but probably doable.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D634

AFFECTED FILES
  mercurial/cext/charencode.c

CHANGE DETAILS

diff --git a/mercurial/cext/charencode.c b/mercurial/cext/charencode.c
--- a/mercurial/cext/charencode.c
+++ b/mercurial/cext/charencode.c
@@ -294,11 +294,21 @@
 				return -1;
 			}
 			esclen += jsonparanoidlentable[(unsigned char)c];
+			if (esclen < 0) {
+				PyErr_SetString(PyExc_MemoryError,
+						"overflow in jsonescapelen");
+				return -1;
+			}
 		}
 	} else {
 		for (i = 0; i < len; i++) {
 			char c = buf[i];
 			esclen += jsonlentable[(unsigned char)c];
+			if (esclen < 0) {
+				PyErr_SetString(PyExc_MemoryError,
+						"overflow in jsonescapelen");
+				return -1;
+			}
 		}
 	}
 
@@ -366,7 +376,7 @@
 	origlen = PyBytes_GET_SIZE(origstr);
 	esclen = jsonescapelen(origbuf, origlen, paranoid);
 	if (esclen < 0)
-		return NULL;  /* unsupported char found */
+		return NULL;  /* unsupported char found or overflow */
 	if (origlen == esclen) {
 		Py_INCREF(origstr);
 		return origstr;



To: singhsrb, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list