Author: brane
Date: Thu Jun 26 03:01:58 2025
New Revision: 1926729
URL: http://svn.apache.org/viewvc?rev=1926729&view=rev
Log:
On the user-defined-authn branch: Detect and parse authn parameters that
are a single (possibly base-64) token.
* serf.h
(serf_authn_get_realm_func_t): Update docstring for the single-token case.
* serf_private.h
(serf__parse_authn_parameters): Likewise.
* src/genctype.py: Generate token68 bits.
* src/syntax.c: Include apr.h, for apr_uint32_t.
(CT_WHITESPACE): Rename from CT_HTTP_SPACE, change value.
(CT_TOKEN): Rename from CT_HTTP_TOKEN, also change value.
(CT_TOKEN68): New; for punctuation that's allowed in a token68.
(char_table): Change type to apr_uint32_t and update contents.
(ct_istoken): Update the bit mask.
(ct_istoken68, skip_token68): New.
(serf__parse_authn_parameters): Detect a single token68 parameter.
Detect when two parameters are not separated by a comma.
* test/test_internal.c
(test_parse_bad_parameters): Remove the "unexpected" result, and the
one case that now passes as a token68 parameter.
(test_parse_single_token_parameters): New, test cases for token68.
(test_internal): Register the new test.
Modified:
serf/branches/user-defined-authn/serf.h
serf/branches/user-defined-authn/serf_private.h
serf/branches/user-defined-authn/src/genctype.py
serf/branches/user-defined-authn/src/syntax.c
serf/branches/user-defined-authn/test/test_internal.c
Modified: serf/branches/user-defined-authn/serf.h
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/serf.h?rev=1926729&r1=1926728&r2=1926729&view=diff
==============================================================================
--- serf/branches/user-defined-authn/serf.h (original)
+++ serf/branches/user-defined-authn/serf.h Thu Jun 26 03:01:58 2025
@@ -1032,10 +1032,14 @@ typedef apr_status_t
*
* @a authn_header and @a authn_parameters come from the authentication header
* (WWW-Authenticate or Proxy-Authenticate) recevied in a server response.
+ *
* @a authn_header is the header value, i.e., "scheme <parameters>";
+ *
* @a authn_parameters is a dictionary of the authentication parameters
* and their values, e.g., `realm="Wonderland"`. The keys are always folded
- * to lower case.
+ * to lower case. If the parameter is a single token, it is returned in the
+ * dictionary as the value of the empty string key ("").
+ * @see https://www.rfc-editor.org/rfc/rfc9110.html#section-11.2
*
* If the scheme flag @a SERF_AUTHN_FLAG_PIPE is *not* set, pipelining will be
* disabled on the connection after this callback succeeds.
Modified: serf/branches/user-defined-authn/serf_private.h
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/serf_private.h?rev=1926729&r1=1926728&r2=1926729&view=diff
==============================================================================
--- serf/branches/user-defined-authn/serf_private.h (original)
+++ serf/branches/user-defined-authn/serf_private.h Thu Jun 26 03:01:58 2025
@@ -750,11 +750,12 @@ serf__authn_info_t *serf__get_authn_info
/* Parse authentication scheme parameters from a WWW-Authenticate or
Proxy-Authenticate header. Splits the comma-separated token=value
- or token="quoted \" value" pairs into a dictionary.
+ or token="quoted \" value" pairs into a dictionary. If the parameters
+ are a single token, it's stored as the value of the empty string key.
The keys in the dictionary will be folded to lowercase.
- See: https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6 */
+ See: https://www.rfc-editor.org/rfc/rfc9110.html#section-11.2 */
apr_hash_t *serf__parse_authn_parameters(const char *attrs, apr_pool_t *pool);
/* Fold ASCII uppercase letters to lowercase, in place, using the same
Modified: serf/branches/user-defined-authn/src/genctype.py
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/src/genctype.py?rev=1926729&r1=1926728&r2=1926729&view=diff
==============================================================================
--- serf/branches/user-defined-authn/src/genctype.py (original)
+++ serf/branches/user-defined-authn/src/genctype.py Thu Jun 26 03:01:58 2025
@@ -51,10 +51,13 @@ utf8_invalid = frozenset((0xE0, 0xF0, 0x
# HTTP classes: whitespace and token punctuation
http_space = (9, 32)
-http_token_punct = frozenset((
+token_punct = frozenset((
33, 35, 36, 37, 38, 39, 42, 43, 45, 46, 94, 95, 96, 124, 126))
# ! # $ % & ' * + - . ^ _ ` | ~
+token68_punct = frozenset((43, 45, 46, 47, 95, 126))
+# + - . / _ ~
+
print(' /* **** DO NOT EDIT! ****')
print(' This table was generated by genctype.py, make changes there. */')
@@ -78,7 +81,7 @@ for c in range(256):
if c in whitespace:
bits.append('CT_SPACE')
if c in http_space:
- bits.append('CT_HTTP_SPACE')
+ bits.append('CT_WHITESPACE')
# Punctuation marks
if c >= 33 and c < 48 \
@@ -86,18 +89,14 @@ for c in range(256):
or c >= 91 and c < 97 \
or c >= 123 and c < 127:
bits.append('CT_PUNCT')
- if c in http_token_punct:
- bits.append('CT_HTTP_TOKEN')
# Decimal digits
elif c >= 48 and c < 58:
bits.append('CT_DIGIT')
- bits.append('CT_HTTP_TOKEN')
# Uppercase letters
elif c >= 65 and c < 91:
bits.append('CT_UPPER')
- bits.append('CT_HTTP_TOKEN')
# Hexadecimal digits
if c <= 70:
bits.append('CT_XALPHA')
@@ -105,11 +104,16 @@ for c in range(256):
# Lowercase letters
elif c >= 97 and c < 123:
bits.append('CT_LOWER')
- bits.append('CT_HTTP_TOKEN')
# Hexadecimal digits
if c <= 102:
bits.append('CT_XALPHA')
+ # token and token68
+ if c in token_punct:
+ bits.append('CT_TOKEN')
+ if c in token68_punct:
+ bits.append('CT_TOKEN68')
+
# UTF-8 multibyte sequences
else:
name = hex(c)[1:]
Modified: serf/branches/user-defined-authn/src/syntax.c
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/src/syntax.c?rev=1926729&r1=1926728&r2=1926729&view=diff
==============================================================================
--- serf/branches/user-defined-authn/src/syntax.c (original)
+++ serf/branches/user-defined-authn/src/syntax.c Thu Jun 26 03:01:58 2025
@@ -18,6 +18,7 @@
* ====================================================================
*/
+#include <apr.h>
#include <apr_pools.h>
#include <apr_hash.h>
@@ -26,32 +27,42 @@
/* Character classes */
-#define CT_ASCII 0x0001
-#define CT_CNTRL 0x0002
-#define CT_SPACE 0x0004
-#define CT_PUNCT 0x0008
-#define CT_DIGIT 0x0010
-#define CT_UPPER 0x0020
-#define CT_LOWER 0x0040
-#define CT_XALPHA 0x0080
-#define CT_UTF8_CONT 0x0100
-#define CT_UTF8_LEAD 0x0200
+#define CT_ASCII 0x0001
+#define CT_CNTRL 0x0002
+#define CT_SPACE 0x0004
+#define CT_PUNCT 0x0008
+#define CT_DIGIT 0x0010
+#define CT_UPPER 0x0020
+#define CT_LOWER 0x0040
+#define CT_XALPHA 0x0080
+#define CT_UTF8_CONT 0x0100
+#define CT_UTF8_LEAD 0x0200
/* Only space and the horizontal tab are treated as whitespace. */
-#define CT_HTTP_SPACE 0x1000
+#define CT_WHITESPACE 0x010000
-/* Characters that are allowed in tokens, accorting to RFC 9110, are the
- ASCII digits, lowercase and uppercase letters, and the following
- punctiation marks:
+/* A `token` is a sequence of ASCII digits, lowercase and uppercase letters,
+ and the following punctiation marks:
! # $ % & ' * + - . ^ _ ` | ~
- Whitespace and all other printable ASCII characters are delimiters. */
-#define CT_HTTP_TOKEN 0x2000
+ See: https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.2
+*/
+#define CT_TOKEN 0x020000
+
+/* A `token68` is a sequence of ASCII digits, lowercase and uppercase letters,
+ and the following punctiation marks:
+
+ - . _ ~ + /
+
+ followed by zero or more `=` signs.
+ See: https://www.rfc-editor.org/rfc/rfc9110.html#section-11.2
+*/
+#define CT_TOKEN68 0x040000
/* ASCII + UTF-8 character table, stolen wholesale from Subversion. */
-static const unsigned short char_table[256] =
+static const apr_uint32_t char_table[256] =
{
/* **** DO NOT EDIT! ****
This table was generated by genctype.py, make changes there. */
@@ -64,7 +75,7 @@ static const unsigned short char_table[2
/* ack */ CT_ASCII | CT_CNTRL,
/* bel */ CT_ASCII | CT_CNTRL,
/* bs */ CT_ASCII | CT_CNTRL,
- /* ht */ CT_ASCII | CT_CNTRL | CT_SPACE | CT_HTTP_SPACE,
+ /* ht */ CT_ASCII | CT_CNTRL | CT_SPACE | CT_WHITESPACE,
/* nl */ CT_ASCII | CT_CNTRL | CT_SPACE,
/* vt */ CT_ASCII | CT_CNTRL | CT_SPACE,
/* np */ CT_ASCII | CT_CNTRL | CT_SPACE,
@@ -87,32 +98,32 @@ static const unsigned short char_table[2
/* gs */ CT_ASCII | CT_CNTRL,
/* rs */ CT_ASCII | CT_CNTRL,
/* us */ CT_ASCII | CT_CNTRL,
- /* sp */ CT_ASCII | CT_SPACE | CT_HTTP_SPACE,
- /* ! */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
+ /* sp */ CT_ASCII | CT_SPACE | CT_WHITESPACE,
+ /* ! */ CT_ASCII | CT_PUNCT | CT_TOKEN,
/* " */ CT_ASCII | CT_PUNCT,
- /* # */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* $ */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* % */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* & */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* ' */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
+ /* # */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* $ */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* % */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* & */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* ' */ CT_ASCII | CT_PUNCT | CT_TOKEN,
/* ( */ CT_ASCII | CT_PUNCT,
/* ) */ CT_ASCII | CT_PUNCT,
- /* * */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* + */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
+ /* * */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* + */ CT_ASCII | CT_PUNCT | CT_TOKEN | CT_TOKEN68,
/* , */ CT_ASCII | CT_PUNCT,
- /* - */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* . */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* / */ CT_ASCII | CT_PUNCT,
- /* 0 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 1 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 2 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 3 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 4 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 5 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 6 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 7 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 8 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
- /* 9 */ CT_ASCII | CT_DIGIT | CT_HTTP_TOKEN,
+ /* - */ CT_ASCII | CT_PUNCT | CT_TOKEN | CT_TOKEN68,
+ /* . */ CT_ASCII | CT_PUNCT | CT_TOKEN | CT_TOKEN68,
+ /* / */ CT_ASCII | CT_PUNCT | CT_TOKEN68,
+ /* 0 */ CT_ASCII | CT_DIGIT,
+ /* 1 */ CT_ASCII | CT_DIGIT,
+ /* 2 */ CT_ASCII | CT_DIGIT,
+ /* 3 */ CT_ASCII | CT_DIGIT,
+ /* 4 */ CT_ASCII | CT_DIGIT,
+ /* 5 */ CT_ASCII | CT_DIGIT,
+ /* 6 */ CT_ASCII | CT_DIGIT,
+ /* 7 */ CT_ASCII | CT_DIGIT,
+ /* 8 */ CT_ASCII | CT_DIGIT,
+ /* 9 */ CT_ASCII | CT_DIGIT,
/* : */ CT_ASCII | CT_PUNCT,
/* ; */ CT_ASCII | CT_PUNCT,
/* < */ CT_ASCII | CT_PUNCT,
@@ -120,68 +131,68 @@ static const unsigned short char_table[2
/* > */ CT_ASCII | CT_PUNCT,
/* ? */ CT_ASCII | CT_PUNCT,
/* @ */ CT_ASCII | CT_PUNCT,
- /* A */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN | CT_XALPHA,
- /* B */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN | CT_XALPHA,
- /* C */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN | CT_XALPHA,
- /* D */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN | CT_XALPHA,
- /* E */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN | CT_XALPHA,
- /* F */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN | CT_XALPHA,
- /* G */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* H */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* I */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* J */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* K */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* L */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* M */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* N */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* O */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* P */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* Q */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* R */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* S */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* T */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* U */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* V */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* W */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* X */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* Y */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
- /* Z */ CT_ASCII | CT_UPPER | CT_HTTP_TOKEN,
+ /* A */ CT_ASCII | CT_UPPER | CT_XALPHA,
+ /* B */ CT_ASCII | CT_UPPER | CT_XALPHA,
+ /* C */ CT_ASCII | CT_UPPER | CT_XALPHA,
+ /* D */ CT_ASCII | CT_UPPER | CT_XALPHA,
+ /* E */ CT_ASCII | CT_UPPER | CT_XALPHA,
+ /* F */ CT_ASCII | CT_UPPER | CT_XALPHA,
+ /* G */ CT_ASCII | CT_UPPER,
+ /* H */ CT_ASCII | CT_UPPER,
+ /* I */ CT_ASCII | CT_UPPER,
+ /* J */ CT_ASCII | CT_UPPER,
+ /* K */ CT_ASCII | CT_UPPER,
+ /* L */ CT_ASCII | CT_UPPER,
+ /* M */ CT_ASCII | CT_UPPER,
+ /* N */ CT_ASCII | CT_UPPER,
+ /* O */ CT_ASCII | CT_UPPER,
+ /* P */ CT_ASCII | CT_UPPER,
+ /* Q */ CT_ASCII | CT_UPPER,
+ /* R */ CT_ASCII | CT_UPPER,
+ /* S */ CT_ASCII | CT_UPPER,
+ /* T */ CT_ASCII | CT_UPPER,
+ /* U */ CT_ASCII | CT_UPPER,
+ /* V */ CT_ASCII | CT_UPPER,
+ /* W */ CT_ASCII | CT_UPPER,
+ /* X */ CT_ASCII | CT_UPPER,
+ /* Y */ CT_ASCII | CT_UPPER,
+ /* Z */ CT_ASCII | CT_UPPER,
/* [ */ CT_ASCII | CT_PUNCT,
/* \ */ CT_ASCII | CT_PUNCT,
/* ] */ CT_ASCII | CT_PUNCT,
- /* ^ */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* _ */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* ` */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
- /* a */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN | CT_XALPHA,
- /* b */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN | CT_XALPHA,
- /* c */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN | CT_XALPHA,
- /* d */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN | CT_XALPHA,
- /* e */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN | CT_XALPHA,
- /* f */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN | CT_XALPHA,
- /* g */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* h */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* i */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* j */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* k */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* l */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* m */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* n */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* o */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* p */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* q */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* r */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* s */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* t */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* u */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* v */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* w */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* x */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* y */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
- /* z */ CT_ASCII | CT_LOWER | CT_HTTP_TOKEN,
+ /* ^ */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* _ */ CT_ASCII | CT_PUNCT | CT_TOKEN | CT_TOKEN68,
+ /* ` */ CT_ASCII | CT_PUNCT | CT_TOKEN,
+ /* a */ CT_ASCII | CT_LOWER | CT_XALPHA,
+ /* b */ CT_ASCII | CT_LOWER | CT_XALPHA,
+ /* c */ CT_ASCII | CT_LOWER | CT_XALPHA,
+ /* d */ CT_ASCII | CT_LOWER | CT_XALPHA,
+ /* e */ CT_ASCII | CT_LOWER | CT_XALPHA,
+ /* f */ CT_ASCII | CT_LOWER | CT_XALPHA,
+ /* g */ CT_ASCII | CT_LOWER,
+ /* h */ CT_ASCII | CT_LOWER,
+ /* i */ CT_ASCII | CT_LOWER,
+ /* j */ CT_ASCII | CT_LOWER,
+ /* k */ CT_ASCII | CT_LOWER,
+ /* l */ CT_ASCII | CT_LOWER,
+ /* m */ CT_ASCII | CT_LOWER,
+ /* n */ CT_ASCII | CT_LOWER,
+ /* o */ CT_ASCII | CT_LOWER,
+ /* p */ CT_ASCII | CT_LOWER,
+ /* q */ CT_ASCII | CT_LOWER,
+ /* r */ CT_ASCII | CT_LOWER,
+ /* s */ CT_ASCII | CT_LOWER,
+ /* t */ CT_ASCII | CT_LOWER,
+ /* u */ CT_ASCII | CT_LOWER,
+ /* v */ CT_ASCII | CT_LOWER,
+ /* w */ CT_ASCII | CT_LOWER,
+ /* x */ CT_ASCII | CT_LOWER,
+ /* y */ CT_ASCII | CT_LOWER,
+ /* z */ CT_ASCII | CT_LOWER,
/* { */ CT_ASCII | CT_PUNCT,
- /* | */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
+ /* | */ CT_ASCII | CT_PUNCT | CT_TOKEN,
/* } */ CT_ASCII | CT_PUNCT,
- /* ~ */ CT_ASCII | CT_PUNCT | CT_HTTP_TOKEN,
+ /* ~ */ CT_ASCII | CT_PUNCT | CT_TOKEN | CT_TOKEN68,
/* del */ CT_ASCII | CT_CNTRL,
/* x80 */ CT_UTF8_CONT,
/* x81 */ CT_UTF8_CONT,
@@ -245,13 +256,6 @@ static const unsigned short char_table[2
/* xbb */ CT_UTF8_CONT,
/* xbc */ CT_UTF8_CONT,
/* xbd */ CT_UTF8_CONT,
- /* xbe */ CT_UTF8_CONT,
- /* xbf */ CT_UTF8_CONT,
- /* xc0 */ 0,
- /* xc1 */ CT_UTF8_LEAD,
- /* xc2 */ CT_UTF8_LEAD,
- /* xc3 */ CT_UTF8_LEAD,
- /* xc4 */ CT_UTF8_LEAD,
/* xc5 */ CT_UTF8_LEAD,
/* xc6 */ CT_UTF8_LEAD,
/* xc7 */ CT_UTF8_LEAD,
@@ -316,12 +320,19 @@ static const unsigned short char_table[2
/* Character class lookup */
static APR_INLINE int ct_isspace(char c)
{
- return char_table[(unsigned char)c] & CT_HTTP_SPACE;
+ return char_table[(unsigned char)c] & CT_WHITESPACE;
}
static APR_INLINE int ct_istoken(char c)
{
- return char_table[(unsigned char)c] & CT_HTTP_TOKEN;
+ static const apr_uint32_t ct = CT_TOKEN | CT_DIGIT | CT_UPPER | CT_LOWER;
+ return ct & char_table[(unsigned char)c];
+}
+
+static APR_INLINE int ct_istoken68(char c)
+{
+ static const apr_uint32_t ct = CT_TOKEN68 | CT_DIGIT | CT_UPPER | CT_LOWER;
+ return ct & char_table[(unsigned char)c];
}
@@ -362,6 +373,15 @@ static const char *skip_space(const char
return src;
}
+static const char *skip_token68(const char *src)
+{
+ while (ct_istoken68(*src))
+ ++src;
+ while (*src == '=')
+ ++src;
+ return src;
+}
+
#if 0
static const char *skip_comment(const char *src)
{
@@ -431,10 +451,19 @@ static const char *copy_token(char **dst
apr_hash_t *serf__parse_authn_parameters(const char *attrs, apr_pool_t *pool)
{
apr_hash_t *dict = apr_hash_make(pool);
- char *dst = apr_palloc(pool, strlen(attrs));
- const char *src = attrs;
+ char *dst = apr_palloc(pool, strlen(attrs) + 1);
+ const char *src = skip_space(attrs);
+ const char *end = skip_token68(src);
bool want_comma = false;
+ /* Check if the parameters are a single token68. */
+ if (end != src && !*skip_space(end)) {
+ memcpy(dst, src, end - src);
+ dst[end - src] = '\0';
+ apr_hash_set(dict, "", 0, dst);
+ return dict;
+ }
+
while (src && *src)
{
const char *key;
@@ -473,7 +502,8 @@ apr_hash_t *serf__parse_authn_parameters
*dst++ = '\0';
/* Must be at the end of the string or at a valid separator. */
- if (*src && *src != ',' && !ct_isspace(*src))
+ src = skip_space(src);
+ if (*src && *src != ',')
break;
/* Put the new key/value pair into the dict. */
Modified: serf/branches/user-defined-authn/test/test_internal.c
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/test_internal.c?rev=1926729&r1=1926728&r2=1926729&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/test_internal.c (original)
+++ serf/branches/user-defined-authn/test/test_internal.c Thu Jun 26 03:01:58
2025
@@ -510,19 +510,14 @@ static void test_parse_bad_parameters(Cu
static const struct expected_attrs expected[] = {
{ NULL, NULL }
};
- static const struct expected_attrs unexpected[] = {
- { "key", "value1" },
- { NULL, NULL }
- };
parse_parameters(tc, "", expected);
parse_parameters(tc, "\t", expected);
parse_parameters(tc, "(comm", expected);
- parse_parameters(tc, "key", expected);
parse_parameters(tc, "key=\"value", expected);
parse_parameters(tc, "key = value", expected);
parse_parameters(tc, "key=\"value1\"key=value2", expected);
- parse_parameters(tc, "key=value1 key=value2", unexpected);
+ parse_parameters(tc, "key=value1 key=value2", expected);
}
static void test_parse_repeated_parameters(CuTest *tc)
@@ -535,6 +530,17 @@ static void test_parse_repeated_paramete
parse_parameters(tc, "key=value1, key=value2", expected);
}
+static void test_parse_single_token_parameters(CuTest *tc)
+{
+ static const struct expected_attrs expected[] = {
+ { "", "Alice/In+Wonderland.==" },
+ { NULL, NULL }
+ };
+
+ parse_parameters(tc, "\tAlice/In+Wonderland.== ", expected);
+ parse_parameters(tc, "Alice=In+Wonderland.=", &expected[1]);
+}
+
static void test_parameter_case_folding(CuTest *tc)
{
static const struct expected_attrs expected[] = {
@@ -564,6 +570,7 @@ CuSuite *test_internal(void)
SUITE_ADD_TEST(suite, test_parse_parameters);
SUITE_ADD_TEST(suite, test_parse_bad_parameters);
SUITE_ADD_TEST(suite, test_parse_repeated_parameters);
+ SUITE_ADD_TEST(suite, test_parse_single_token_parameters);
SUITE_ADD_TEST(suite, test_parameter_case_folding);
return suite;