22
33namespace HJSON ;
44
5+ /**
6+ * NOTE: this may return an empty string at the end of the array when the input
7+ * string ends with a newline character
8+ */
59function mb_str_split ($ string )
610{
7- return preg_split ('/(?<!^)(?!$) /u ' , $ string );
11+ return preg_split ('/(?<!^)/u ' , $ string );
812}
913
1014class HJSONStringifier
@@ -13,11 +17,12 @@ class HJSONStringifier
1317 // needsEscape tests if the string can be written without escapes
1418 private $ needsEscape = '/[ \\\"\x00-\x1f\x7f-\x9f\x{00ad}\x{0600}-\x{0604}\x{070f}\x{17b4}\x{17b5}\x{200c}-\x{200f}\x{2028}-\x{202f}\x{2060}-\x{206f}\x{feff}\x{fff0}-\x{ffff}\x]/u ' ;
1519 // needsQuotes tests if the string can be written as a quoteless string (includes needsEscape but without \\ and \")
16- private $ needsQuotes = '/^ \\s|^"|^ \'\'\'|^#|^ \\/ \\*|^ \\/ \\/|^ \\{|^ \\}|^ \\[|^ \\]|^:|^,| \\s$|[\x00-\x1f\x7f-\x9f\x{00ad}\x{0600}-\x{0604}\x{070f}\x{17b4}\x{17b5}\x{200c}-\x{200f}\x{2028}-\x{202f}\x{2060}-\x{206f}\x{feff}\x{fff0}-\x{ffff}\x]/u ' ;
20+ private $ needsQuotes = '/^ \\s|^"|^ \'|^ \' \'\'|^#|^ \\/ \\*|^ \\/ \\/|^ \\{|^ \\}|^ \\[|^ \\]|^:|^,| \\s$|[\x00-\x1f\x7f-\x9f\x{00ad}\x{0600}-\x{0604}\x{070f}\x{17b4}\x{17b5}\x{200c}-\x{200f}\x{2028}-\x{202f}\x{2060}-\x{206f}\x{feff}\x{fff0}-\x{ffff}\x]/u ' ;
1721 // needsEscapeML tests if the string can be written as a multiline string (includes needsEscape but without \n, \r, \\ and \")
18- private $ needsEscapeML = '/ \'\'\'|[\x00-\x09\x0b\x0c\x0e-\x1f\x7f-\x9f\x{00ad}\x{0600}-\x{0604}\x{070f}\x{17b4}\x{17b5}\x{200c}-\x{200f}\x{2028}-\x{202f}\x{2060}-\x{206f}\x{feff}\x{fff0}-\x{ffff}\x]/u ' ;
22+ private $ needsEscapeML = '/ \'\'\'|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f\x{00ad}\x{0600}-\x{0604}\x{070f}\x{17b4}\x{17b5}\x{200c}-\x{200f}\x{2028}-\x{202f}\x{2060}-\x{206f}\x{feff}\x{fff0}-\x{ffff}\x]/u ' ;
23+ private $ onlyWhitespace = '/^ \\s+$/ ' ;
1924 private $ startsWithKeyword = '/^(true|false|null)\s*((,|\]|\}|#|\/\/|\/\*).*)?$/ ' ;
20- private $ needsEscapeName = '/[,\{\[\}\]\s:#"]|\/\/|\/\*| \'\'\'/ ' ;
25+ private $ needsEscapeName = '/[,\{\[\}\]\s:#" \' ]|\/\/|\/\*| \'\'\'/ ' ;
2126 private $ gap = '' ;
2227 private $ indent = ' ' ;
2328
@@ -38,6 +43,7 @@ public function __construct()
3843 "\n" => "\\n " ,
3944 "\r" => "\\r " ,
4045 '" ' => '\\" ' ,
46+ '\'' => '\\\'' ,
4147 '\\' => "\\\\"
4248 ];
4349 $ this ->meta [chr (8 )] = '\\b ' ;
@@ -136,7 +142,11 @@ private function quote($string = null, $gap = null, $hasComment = null, $isRootO
136142
137143 if (!preg_match ($ this ->needsEscape , $ string )) {
138144 return '" ' . $ string . '" ' ;
139- } elseif (!preg_match ($ this ->needsEscapeML , $ string ) && !$ isRootObject ) {
145+ } elseif (
146+ !preg_match ($ this ->needsEscapeML , $ string ) &&
147+ !preg_match ($ this ->onlyWhitespace , $ string ) &&
148+ !$ isRootObject
149+ ) {
140150 return $ this ->mlString ($ string , $ gap );
141151 } else {
142152 return '" ' . $ this ->quoteReplace ($ string ) . '" ' ;
0 commit comments