Browse Source

Rework parsing authority and path from URI.

Do not allocate an empty string if the authority part of the URI is
empty empty, store it as NULL instead. Only allow that if the scheme is
file://, otherwise error out.

Detect if the path portion is reduced to the initial '/', and error out
in that case.
master
Damien Goutte-Gattat 3 months ago
parent
commit
38b4c0ddba
  1. 48
      src/secretcfg.c
  2. 52
      tests/t-parseuri.c

48
src/secretcfg.c

@ -73,21 +73,27 @@ get_line(FILE *f, char *buffer, size_t len)
* @param uri The address of the URI string. The pointer is
* advanced to the '/' character separating the
* authority from the path.
* @param authority The address of a newly allocated buffer to
* store the authority.
*
* @return A newly-allocated string containing the authority, or
* NULL if the uri did not contain a '/' character.
* @return 0 if the authority was successfully extracted, or
* GFSEC_ERR_CONFIG_INVALID_URI if the uri did not contain a '/'
* character.
*/
static char *
parse_authority(const char **uri)
static int
parse_authority(const char **uri, char **authority)
{
char *slash, *authority = NULL;
char *slash;
if ( ! (slash = strchr(*uri, '/')) )
return GFSEC_ERR_CONFIG_INVALID_URI;
if ( (slash = strchr(*uri, '/')) ) {
authority = xstrndup(*uri, slash - *uri);
if ( slash > *uri ) {
*authority = xstrndup(*uri, slash - *uri);
*uri = slash;
}
return authority;
return 0;
}
/**
@ -98,19 +104,26 @@ parse_authority(const char **uri)
* @param uri The address of the URI string. The pointer is advanced
* to the first '?' character, or to the terminating NULL
* byte.
* @param path The address of a newly allocated buffer to store the
* extracted path.
*
* @return A newly-allocated buffer containing the path.
* @return 0 if the path was successfully parsed, or
* GFSEC_ERR_CONFIG_INVALID_URI if either the path is empty or it ends
* with a directory separator.
*/
static char *
parse_path(const char **uri)
static int
parse_path(const char **uri, char **path)
{
char *qm, *path;
char *qm;
qm = strchrnul(*uri, '?');
path = xstrndup(*uri, qm - *uri);
if ( qm == *uri || *(qm - 1) == '/' )
return GFSEC_ERR_CONFIG_INVALID_URI;
*path = xstrndup(*uri, qm - *uri);
*uri = qm;
return path;
return 0;
}
/**
@ -302,11 +315,14 @@ gfsec_parse_uri(const char *uri, gfsec_secret_t *secret, int assign)
else
rc = GFSEC_ERR_CONFIG_UNKNOWN_SCHEME;
if ( rc == 0 && ! (share->authority = parse_authority(&p)) )
if ( rc == 0 )
rc = parse_authority(&p, &(share->authority));
if ( ! share->authority && share->scheme != GFSEC_SCHEME_FILE )
rc = GFSEC_ERR_CONFIG_INVALID_URI;
if ( rc == 0 )
share->path = parse_path(&p);
rc = parse_path(&p, &(share->path));
while ( rc == 0 && *p )
rc = parse_parameter(&p, share);

52
tests/t-parseuri.c

@ -53,30 +53,38 @@ struct test tests[] = {
/* Recognizing the valid schemes. */
{ "file:///path/to/share.123",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 123, 0 },
{ "uuid:///path/to/share.123",
0, GFSEC_SCHEME_UUID, "", "/path/to/share.123", 123, 0 },
{ "mtp:///path/to/share.123",
0, GFSEC_SCHEME_MTP, "", "/path/to/share.123", 123, 0 },
{ "label:///path/to/share.123",
0, GFSEC_SCHEME_LABEL, "", "/path/to/share.123", 123, 0 },
{ "http:///path/to/share.123",
0, GFSEC_SCHEME_HTTP, "", "/path/to/share.123", 123, 0 },
{ "https:///path/to/share.123",
0, GFSEC_SCHEME_HTTPS, "", "/path/to/share.123", 123, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 123, 0 },
{ "uuid://UUID/path/to/share.123",
0, GFSEC_SCHEME_UUID, "UUID", "/path/to/share.123", 123, 0 },
{ "mtp://SERIAL/path/to/share.123",
0, GFSEC_SCHEME_MTP, "SERIAL", "/path/to/share.123", 123, 0 },
{ "label://LABEL/path/to/share.123",
0, GFSEC_SCHEME_LABEL, "LABEL", "/path/to/share.123", 123, 0 },
{ "http://HOST/path/to/share.123",
0, GFSEC_SCHEME_HTTP, "HOST", "/path/to/share.123", 123, 0 },
{ "https://HOST/path/to/share.123",
0, GFSEC_SCHEME_HTTPS, "HOST", "/path/to/share.123", 123, 0 },
{ "scheme:///path/to/share.123", GFSEC_ERR_CONFIG_UNKNOWN_SCHEME },
/* Empty path. */
{ "file:///", GFSEC_ERR_CONFIG_INVALID_URI },
{ "file:///?param=value", GFSEC_ERR_CONFIG_INVALID_URI },
/* Path ending with a directory separator. */
{ "file:///path/", GFSEC_ERR_CONFIG_INVALID_URI },
{ "file:///path/?param=value", GFSEC_ERR_CONFIG_INVALID_URI },
/* Several parameters. */
{ "file:///path/to/share.123?param1=val1&param2=val2&param3=val3",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 123, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 123, 0 },
{ "file:///path/to/share.123?param1=val&share=no&param3=val3",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 0, 1 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 0, 1 },
/* Empty parameters. */
{ "file:///path/to/share.123?param1=val&&share=124",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 124, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 124, 0 },
{ "file:///path/to/share.123?&share=124&",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 124, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 124, 0 },
/* Parameter with no value. */
{ "file:///path/to/share.123?param", GFSEC_ERR_CONFIG_INVALID_URI },
@ -91,19 +99,19 @@ struct test tests[] = {
/* Handling the share parameter. */
{ "file:///path/to/share?share=no",
0, GFSEC_SCHEME_FILE, "", "/path/to/share", 0, 1 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share", 0, 1 },
{ "file:///path/to/share.123?share=no",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 0, 1 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 0, 1 },
{ "file:///path/to/share?share=full",
0, GFSEC_SCHEME_FILE, "", "/path/to/share", 0, 1 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share", 0, 1 },
{ "file:///path/to/share.123?share=full",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 0, 1 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 0, 1 },
{ "file:///path/to/share?share=invalid", GFSEC_ERR_CONFIG_INVALID_SHARENR },
{ "file:///path/to/share.123?share=invalid", GFSEC_ERR_CONFIG_INVALID_SHARENR },
{ "file:///path/to/share?share=124",
0, GFSEC_SCHEME_FILE, "", "/path/to/share", 124, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share", 124, 0 },
{ "file:///path/to/share.123?share=124",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 124, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 124, 0 },
/* Hash with invalid length. */
{ "file:///path/to/share.123?sha256=decafbad", GFSEC_ERR_CONFIG_INVALID_HASH },
@ -112,7 +120,7 @@ struct test tests[] = {
GFSEC_ERR_CONFIG_INVALID_HASH },
{ "file:///path/to/share.123?sha256="
"decafbaddecafbaddecafbaddecafbaddecafbaddecafbaddecafbaddecafbad",
0, GFSEC_SCHEME_FILE, "", "/path/to/share.123", 123, 0 },
0, GFSEC_SCHEME_FILE, NULL, "/path/to/share.123", 123, 0 },
/* Hash with invalid characters. */
{ "file:///path/to/share.123?sha256="

Loading…
Cancel
Save