improve URI path checking, make it more strict and simplify logic

This commit is contained in:
Christian Grothoff 2022-03-04 22:29:29 +01:00
parent d0b27833b2
commit 3a1f418603
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC

View File

@ -444,7 +444,7 @@ proceed_with_handler (struct TEH_RequestContext *rc,
size_t *upload_data_size) size_t *upload_data_size)
{ {
const struct TEH_RequestHandler *rh = rc->rh; const struct TEH_RequestHandler *rh = rc->rh;
const char *args[rh->nargs + 1]; const char *args[rh->nargs + 2];
size_t ulen = strlen (url) + 1; size_t ulen = strlen (url) + 1;
json_t *root = NULL; json_t *root = NULL;
MHD_RESULT ret; MHD_RESULT ret;
@ -492,15 +492,10 @@ proceed_with_handler (struct TEH_RequestContext *rc,
{ {
char d[ulen]; char d[ulen];
/* Parse command-line arguments, if applicable */
args[0] = NULL;
if (rh->nargs > 0)
{
unsigned int i; unsigned int i;
const char *fin;
char *sp; char *sp;
/* Parse command-line arguments */
/* make a copy of 'url' because 'strtok_r()' will modify */ /* make a copy of 'url' because 'strtok_r()' will modify */
memcpy (d, memcpy (d,
url, url,
@ -508,23 +503,21 @@ proceed_with_handler (struct TEH_RequestContext *rc,
i = 0; i = 0;
args[i++] = strtok_r (d, "/", &sp); args[i++] = strtok_r (d, "/", &sp);
while ( (NULL != args[i - 1]) && while ( (NULL != args[i - 1]) &&
(i < rh->nargs) ) (i <= rh->nargs + 1) )
args[i++] = strtok_r (NULL, "/", &sp); args[i++] = strtok_r (NULL, "/", &sp);
/* make sure above loop ran nicely until completion, and also /* make sure above loop ran nicely until completion, and also
that there is no excess data in 'd' afterwards */ that there is no excess data in 'd' afterwards */
if ( (! rh->nargs_is_upper_bound) && if ( ( (rh->nargs_is_upper_bound) &&
( (i != rh->nargs) || (i - 1 > rh->nargs) ) ||
(NULL == args[i - 1]) || ( (! rh->nargs_is_upper_bound) &&
(NULL != (fin = strtok_r (NULL, "/", &sp))) ) ) (i - 1 != rh->nargs) ) )
{ {
char emsg[128 + 512]; char emsg[128 + 512];
GNUNET_snprintf (emsg, GNUNET_snprintf (emsg,
sizeof (emsg), sizeof (emsg),
"Got %u/%u segments for %s request ('%s')", "Got %u+/%u segments for `%s' request (`%s')",
(NULL == args[i - 1]) i - 1,
? i - 1
: i + ((NULL != fin) ? 1 : 0),
rh->nargs, rh->nargs,
rh->url, rh->url,
url); url);
@ -535,11 +528,7 @@ proceed_with_handler (struct TEH_RequestContext *rc,
TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS, TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,
emsg); emsg);
} }
GNUNET_assert (NULL == args[i - 1]);
/* just to be safe(r), we always terminate the array with a NULL
(even if handlers requested precise number of arguments) */
args[i] = NULL;
}
/* Above logic ensures that 'root' is exactly non-NULL for POST operations, /* Above logic ensures that 'root' is exactly non-NULL for POST operations,
so we test for 'root' to decide which handler to invoke. */ so we test for 'root' to decide which handler to invoke. */