var: add a '64dec' function that can base64 decode a string

Verified in test 455 and 487.

If the provided string cannot be base64-decoded, it will instead use
"[64dec-fail]" (without the quotes).

Documented

Ref: #16288
Closes #16330
This commit is contained in:
Daniel Stenberg 2025-02-22 10:49:19 +01:00
parent 54c07fd6c5
commit a6e8ead533
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
6 changed files with 101 additions and 11 deletions

View File

@ -27,10 +27,10 @@ set:
When expanding variables, curl supports a set of functions that can make the When expanding variables, curl supports a set of functions that can make the
variable contents more convenient to use. It can trim leading and trailing variable contents more convenient to use. It can trim leading and trailing
white space with `trim`, it can output the contents as a JSON quoted string white space with `trim`, it can output the contents as a JSON quoted string
with `json`, URL encode the string with `url` or base64 encode it with `b64`. with `json`, URL encode the string with `url`, base64 encode it with `b64` and
To apply functions to a variable expansion, add them colon separated to the base64 decode it with `64dec`. To apply functions to a variable expansion, add
right side of the variable. Variable content holding null bytes that are not them colon separated to the right side of the variable. Variable content
encoded when expanded cause error. holding null bytes that are not encoded when expanded cause error.
Example: get the contents of a file called $HOME/.secret into a variable Example: get the contents of a file called $HOME/.secret into a variable
called "fix". Make sure that the content is trimmed and percent-encoded when called "fix". Make sure that the content is trimmed and percent-encoded when

View File

@ -66,30 +66,45 @@ error.
Available functions: Available functions:
## trim ## `trim`
removes all leading and trailing white space. removes all leading and trailing white space.
Example: Example:
curl --expand-url https://example.com/{{var:trim}} curl --expand-url https://example.com/{{var:trim}}
## json ## `json`
outputs the content using JSON string quoting rules. outputs the content using JSON string quoting rules.
Example: Example:
curl --expand-data {{data:json}} https://example.com curl --expand-data {{data:json}} https://example.com
## url ## `url`
shows the content URL (percent) encoded. shows the content URL (percent) encoded.
Example: Example:
curl --expand-url https://example.com/{{path:url}} curl --expand-url https://example.com/{{path:url}}
## b64 ## `b64`
expands the variable base64 encoded expands the variable base64 encoded
Example: Example:
curl --expand-url https://example.com/{{var:b64}} curl --expand-url https://example.com/{{var:b64}}
## `64dec`
decodes a base64 encoded character sequence. If the sequence is not possible
to decode, it instead outputs `[64dec-fail]`
Example:
curl --expand-url https://example.com/{{var:64dec}}
(Added in 8.13.0)

View File

@ -91,6 +91,8 @@ static const struct tool_var *varcontent(struct GlobalConfig *global,
#define FUNC_URL_LEN (sizeof(FUNC_URL) - 1) #define FUNC_URL_LEN (sizeof(FUNC_URL) - 1)
#define FUNC_B64 "b64" #define FUNC_B64 "b64"
#define FUNC_B64_LEN (sizeof(FUNC_B64) - 1) #define FUNC_B64_LEN (sizeof(FUNC_B64) - 1)
#define FUNC_64DEC "64dec" /* base64 decode */
#define FUNC_64DEC_LEN (sizeof(FUNC_64DEC) - 1)
static ParameterError varfunc(struct GlobalConfig *global, static ParameterError varfunc(struct GlobalConfig *global,
char *c, /* content */ char *c, /* content */
@ -179,6 +181,27 @@ static ParameterError varfunc(struct GlobalConfig *global,
break; break;
} }
} }
else if(FUNCMATCH(f, FUNC_64DEC, FUNC_64DEC_LEN)) {
f += FUNC_64DEC_LEN;
curlx_dyn_reset(out);
if(clen) {
unsigned char *enc;
size_t elen;
CURLcode result = curlx_base64_decode(c, &enc, &elen);
/* put it in the output */
if(result) {
if(curlx_dyn_add(out, "[64dec-fail]"))
err = PARAM_NO_MEM;
}
else {
if(curlx_dyn_addn(out, enc, elen))
err = PARAM_NO_MEM;
curl_free(enc);
}
if(err)
break;
}
}
else { else {
/* unsupported function */ /* unsupported function */
errorf(global, "unknown variable function in '%.*s'", errorf(global, "unknown variable function in '%.*s'",

View File

@ -78,7 +78,7 @@ test444 test445 test446 test447 test448 test449 test450 test451 test452 \
test453 test454 test455 test456 test457 test458 test459 test460 test461 \ test453 test454 test455 test456 test457 test458 test459 test460 test461 \
test462 test463 test467 test468 test469 test470 test471 test472 test473 \ test462 test463 test467 test468 test469 test470 test471 test472 test473 \
test474 test475 test476 test477 test478 test479 test480 test481 test482 \ test474 test475 test476 test477 test478 test479 test480 test481 test482 \
test483 test484 test485 test486 \ test483 test484 test485 test486 test487 \
test490 test491 test492 test493 test494 test495 test496 test497 test498 \ test490 test491 test492 test493 test494 test495 test496 test497 test498 \
test499 test500 test501 test502 test503 test504 test505 test506 test507 \ test499 test500 test501 test502 test503 test504 test505 test506 test507 \
test508 test509 test510 test511 test512 test513 test514 test515 test516 \ test508 test509 test510 test511 test512 test513 test514 test515 test516 \

View File

@ -34,7 +34,7 @@ http
Variable using base64 Variable using base64
</name> </name>
<command> <command>
--variable moby="Call me Ishmael" --expand-url "http://%HOSTIP:%HTTPPORT/{{moby:b64}}/%TESTNUMBER" --variable moby="Call me Ishmael" --variable what=%b64[white-whale]b64% --expand-url "http://%HOSTIP:%HTTPPORT/{{moby:b64}}/{{what:64dec}}/%TESTNUMBER"
</command> </command>
</client> </client>
@ -42,7 +42,7 @@ Variable using base64
# Verify data after the test has been "shot" # Verify data after the test has been "shot"
<verify> <verify>
<protocol crlf="yes"> <protocol crlf="yes">
GET /%b64[Call me Ishmael]b64%/%TESTNUMBER HTTP/1.1 GET /%b64[Call me Ishmael]b64%/white-whale/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION User-Agent: curl/%VERSION
Accept: */* Accept: */*

52
tests/data/test487 Normal file
View File

@ -0,0 +1,52 @@
<testcase>
<info>
<keywords>
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>
Variable using 64dec with bad base64
</name>
<command>
--variable what=not-base64-data --expand-url "http://%HOSTIP:%HTTPPORT/{{what:64dec}}/%TESTNUMBER" -g
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol crlf="yes">
GET /[64dec-fail]/%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
</verify>
</testcase>