com php-src: Improved UTF-8 validation in JSON: ext/json/json _encoder.c

[email protected] (Dmitry Stogov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    13ee8fd626accebd93f943d2d1d23a6e952e060f
Author:    Dmitry Stogov <[email protected]>         Thu, 25 May 2017 01:16:17 +0300
Parents:   fa828dbe841c654dd7ac87c26929b873168eaea2
Branches:  master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=13ee8fd626accebd93f943d2d1d23a6e952e060f

Log:
Improved UTF-8 validation in JSON

Changed paths:
  M  ext/json/json_encoder.c


Diff:
diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c
index c88d355..545d229 100644
--- a/ext/json/json_encoder.c
+++ b/ext/json/json_encoder.c
@@ -246,40 +246,23 @@ static int php_json_encode_array(smart_str *buf, zval *val, int options, php_jso
 }
 /* }}} */
 
-static int php_json_utf8_to_utf16(unsigned short *utf16, char utf8[], size_t len) /* {{{ */
+static int php_json_valid_utf8(char utf8[], size_t len) /* {{{ */
 {
 	size_t pos = 0, us;
-	int j, status;
+	int status;
 
-	if (utf16) {
-		/* really convert the utf8 string */
-		for (j=0 ; pos < len ; j++) {
-			us = php_next_utf8_char((const unsigned char *)utf8, len, &pos, &status);
-			if (status != SUCCESS) {
-				return -1;
-			}
-			/* From http://en.wikipedia.org/wiki/UTF16 */
-			if (us >= 0x10000) {
-				us -= 0x10000;
-				utf16[j++] = (unsigned short)((us >> 10) | 0xd800);
-				utf16[j] = (unsigned short)((us & 0x3ff) | 0xdc00);
-			} else {
-				utf16[j] = (unsigned short)us;
-			}
-		}
-	} else {
-		/* Only check if utf8 string is valid, and compute utf16 length */
-		for (j=0 ; pos < len ; j++) {
+	while (pos < len) {
+		us = (unsigned char)utf8[pos];
+		if (us < 0x80) {
+			pos++;
+		} else {
 			us = php_next_utf8_char((const unsigned char *)utf8, len, &pos, &status);
 			if (status != SUCCESS) {
-				return -1;
-			}
-			if (us >= 0x10000) {
-				j++;
+				return 0;
 			}
 		}
 	}
-	return j;
+	return 1;
 }
 /* }}} */
 
@@ -315,7 +298,7 @@ static int php_json_escape_string(
 
 	if (options & PHP_JSON_UNESCAPED_UNICODE) {
 		/* validate UTF-8 string first */
-		if (php_json_utf8_to_utf16(NULL, s, len) < 0) {
+		if (!php_json_valid_utf8(s, len)) {
 			encoder->error_code = PHP_JSON_ERROR_UTF8;
 			if (options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR) {
 				smart_str_appendl(buf, "null", 4);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.