]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tool_writeout_json: fix JSON encoding of non-ascii bytes
authorEmanuele Torre <torreemanuele6@gmail.com>
Fri, 1 Dec 2023 00:51:47 +0000 (01:51 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 1 Dec 2023 09:39:13 +0000 (10:39 +0100)
char variables if unspecified can be either signed or unsigned depending
on the platform according to the C standard; in most platforms, they are
signed.

This meant that the  *i<32  waas always true for bytes with the top bit
set. So they were always getting encoded as \uXXXX, and then since they
were also signed negative, they were getting extended with 1s causing
'\xe2' to be expanded to \uffffffe2, for example:

  $ curl --variable 'v=“' --expand-write-out '{{v:json}}\n' file:///dev/null
  \uffffffe2\uffffff80\uffffff9c

I fixed this bug by making the code use explicitly unsigned char*
variables instead of char* variables.

Test 268 verifies

Reported-by: iconoclasthero
Closes #12434

src/tool_writeout_json.c
tests/data/Makefile.inc
tests/data/test268 [new file with mode: 0644]

index 7bc74a269721ac6ded4a65e74302e94fc64a7c57..4ed6b93fb7e53f534f574005797d8fe5149820cf 100644 (file)
@@ -41,8 +41,8 @@
 int jsonquoted(const char *in, size_t len,
                struct curlx_dynbuf *out, bool lowercase)
 {
-  const char *i = in;
-  const char *in_end = &in[len];
+  const unsigned char *i = (unsigned char *)in;
+  const unsigned char *in_end = &i[len];
   CURLcode result = CURLE_OK;
 
   for(; (i < in_end) && !result; i++) {
index 2608e16d6e6dd7a27b1d8b884a658d93e78332d9..de13c525e8ff81a834e91fb88235790de9a200a0 100644 (file)
@@ -51,7 +51,7 @@ test226 test227 test228 test229 test230 test231 test232 test233 test234 \
 test235 test236 test237 test238 test239 test240 test241 test242 test243 \
 test244 test245 test246 test247 test248 test249 test250 test251 test252 \
 test253 test254 test255 test256 test257 test258 test259 test260 test261 \
-test262 test263 test264 test265 test266 test267 test269 test270 \
+test262 test263 test264 test265 test266 test267 test268 test269 test270 \
 test271 test272 test273 test274 test275 test276 test277 test278 test279 \
 test280 test281 test282 test283 test284 test285 test286 test287 test288 \
 test289 test290 test291 test292 test293 test294 test295 test296 test297 \
diff --git a/tests/data/test268 b/tests/data/test268
new file mode 100644 (file)
index 0000000..3a1ab6a
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+variables
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data crlf="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
+ETag: "21025-dc7-39462498"
+Accept-Ranges: bytes
+Content-Length: 6
+Connection: close
+Content-Type: text/html
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+JSON encoding of unicode string
+</name>
+<file name="%LOGDIR/junk" nonewline="yes">
+%hex[%e2%80%9c]hex%
+</file>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER --variable hello@%LOGDIR/junk --expand-data {{hello:json}}
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="yes" nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+Content-Length: 3
+Content-Type: application/x-www-form-urlencoded
+
+%hex[%e2%80%9c]hex%
+</protocol>
+</verify>
+</testcase>