Skip to content

Commit

Permalink
trurl: add "strict:" as prefix to a get component
Browse files Browse the repository at this point in the history
The strict prefix makes trurl immediately exit with an error code if
such a get can't be done due to URL decoding problems. By default, such
a problem will only make trurl skip that part and silently continue.

Use it like this: --get "{strict:query}"

I also made "url:" a valid prefix, and now we consider the single colon
prefix to be a shortcut for url:. The concept of prefixes scale better
when we use real words instead of single characters.

Fixes #305
Closes #310
  • Loading branch information
bagder committed Jun 12, 2024
1 parent d30df8a commit c51017c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 11 deletions.
28 changes: 28 additions & 0 deletions tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -2544,5 +2544,33 @@
"stderr": "",
"returncode": 0
}
},
{
"input": {
"arguments": [
"https://curl.se?name=mr%00smith",
"--get",
"{query}"
]
},
"expected": {
"stderr": "trurl note: URL decode error, most likely because of rubbish in the input (query)\n",
"returncode": 0,
"stdout": "\n"
}
},
{
"input": {
"arguments": [
"https://curl.se?name=mr%00smith",
"--get",
"{strict:query}"
]
},
"expected": {
"stderr": "trurl error: problems URL decoding query\ntrurl error: Try trurl -h for help\n",
"returncode": 10,
"stdout": ""
}
}
]
13 changes: 10 additions & 3 deletions trurl.1
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,17 @@ user, password, options, host, port, path, query, fragment and zoneid.
not have a value.

Components are shown URL decoded by default. If you instead write the
component prefixed with a colon like "{:path}", it gets output URL encoded.
component prefixed with "url:" like "{url:path}", it gets output URL encoded.
As a shortcut, "url:" also works written as a single colon: "{:path}".

You may also prefix components with \fBdefault:\fP and/or \fBpuny:\fP or \fBidn:\fP,
in any order.
URL decoding a component may cause problems to display it. Such problems make
a warning get displayed unless \fB--quiet\fP is used. URL decode problems can
optionally be turned into errors by prefixing the comopnent name with
"strict:", as in "{strict:path}". In this stricter mode, a URL decode problem
makes trurl stop what it is doing and return with exit code 10.

You may also prefix components with \fBdefault:\fP and/or \fBpuny:\fP or
\fBidn:\fP, in any order.

If \fBdefault:\fP is specified, like "{default:url}" or
"{default:port}", and the port is not explicitly specified in the URL,
Expand Down
25 changes: 17 additions & 8 deletions trurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,7 @@ static void get(struct option *o, CURLU *uh)
size_t vlen;
bool isquery = false;
bool queryall = false;
bool strict = false; /* strict mode, fail on URL decode problems */
int mods = 0;
end = strchr(ptr, endbyte);
ptr++; /* pass the { */
Expand All @@ -766,39 +767,44 @@ static void get(struct option *o, CURLU *uh)
continue;
}

/* {path} {:path} */
/* {path} {:path} {/path} */
if(*ptr == ':') {
mods |= VARMODIFIER_URLENCODED;
ptr++;
}
vlen = end - ptr;
do {
size_t wordlen;
cl = memchr(ptr, ':', vlen);
if(!cl)
break;
wordlen = cl - ptr + 1;

/* modifiers! */
if(!strncmp(ptr, "default:", cl - ptr + 1))
if(!strncmp(ptr, "default:", wordlen))
mods |= VARMODIFIER_DEFAULT;
else if(!strncmp(ptr, "puny:", cl - ptr + 1)) {
else if(!strncmp(ptr, "puny:", wordlen)) {
if(mods & VARMODIFIER_PUNY2IDN)
errorf(o, ERROR_GET,
"puny modifier is mutually exclusive with idn");
mods |= VARMODIFIER_PUNY;
}
else if(!strncmp(ptr, "idn:", cl - ptr + 1)) {
else if(!strncmp(ptr, "idn:", wordlen)) {
if(mods & VARMODIFIER_PUNY)
errorf(o, ERROR_GET,
"idn modifier is mutually exclusive with puny");
mods |= VARMODIFIER_PUNY2IDN;
}
else if(!strncmp(ptr, "strict:", wordlen))
strict = true;
else if(!strncmp(ptr, "url:", wordlen))
mods |= VARMODIFIER_URLENCODED;
else {
/* {query: or {query-all: */
if(!strncmp(ptr, "query-all:", cl - ptr + 1)) {
if(!strncmp(ptr, "query-all:", wordlen)) {
isquery = true;
queryall = true;
}
else if(!strncmp(ptr, "query:", cl - ptr + 1))
else if(!strncmp(ptr, "query:", wordlen))
isquery = true;
else {
/* syntax error */
Expand Down Expand Up @@ -844,7 +850,10 @@ static void get(struct option *o, CURLU *uh)
/* silently ignore */
break;
default:
trurl_warnf(o, "%s (%s)", curl_url_strerror(rc), v->name);
if((rc == CURLUE_URLDECODE) && strict)
errorf(o, ERROR_GET, "problems URL decoding %s", v->name);
else
trurl_warnf(o, "%s (%s)", curl_url_strerror(rc), v->name);
break;
}
}
Expand Down

0 comments on commit c51017c

Please sign in to comment.