The RFC recommends this be allowed, because `&' is special in HTML.
It's also used by various CGI scripts.
void url_enc(url_ectx *ctx, dstr *d, const char *name, const char *value)
{
if (ctx->f & URLF_SEP)
void url_enc(url_ectx *ctx, dstr *d, const char *name, const char *value)
{
if (ctx->f & URLF_SEP)
+ DPUTC(d, (ctx->f & URLF_SEMI) ? ';' : '&');
encode(ctx, d, name);
DPUTC(d, '=');
encode(ctx, d, value);
encode(ctx, d, name);
DPUTC(d, '=');
encode(ctx, d, value);
* Use: Initializes a URL decoding context.
*/
* Use: Initializes a URL decoding context.
*/
-void url_initdec(url_dctx *ctx, const char *p) { ctx->p = p; }
+void url_initdec(url_dctx *ctx, const char *p) { ctx->p = p; ctx->f = 0; }
- * Arguments: @dstr *d@ = pointer to output string
+ * Arguments: @url_dctx *ctx@ = pointer to the context
+ * @dstr *d@ = pointer to output string
* @const char *p@ = pointer to input data
* @int eq@ = whether to stop at `=' characters
*
* @const char *p@ = pointer to input data
* @int eq@ = whether to stop at `=' characters
*
* Use: Does a URL decode.
*/
* Use: Does a URL decode.
*/
-static const char *decode(dstr *d, const char *p, int eq)
+static const char *decode(url_dctx *ctx, dstr *d, const char *p, int eq)
case '=':
if (eq)
return (p);
case '=':
if (eq)
return (p);
+ goto boring;
+ case ';':
+ if (ctx->f & URLF_SEMI)
+ return (p);
+ goto boring;
case 0:
case '&':
return (p);
case 0:
case '&':
return (p);
size_t l = n->len;
again:
size_t l = n->len;
again:
- if ((p = decode(n, p, 1)) == 0 || *p == 0)
+ if ((p = decode(ctx, n, p, 1)) == 0 || *p == 0)
return (0);
if (*p != '=') {
p++;
return (0);
if (*p != '=') {
p++;
- if ((p = decode(v, p, 0)) == 0)
+ if ((p = decode(ctx, v, p, 0)) == 0)
return (0);
DPUTZ(n);
DPUTZ(v);
return (0);
DPUTZ(n);
DPUTZ(v);
-#define URLF_SEP 1u
-#define URLF_STRICT 2u
-#define URLF_LAX 4u
typedef struct url_dctx {
const char *p;
typedef struct url_dctx {
const char *p;
+#define URLF_SEP 1u
+#define URLF_STRICT 2u
+#define URLF_LAX 4u
+#define URLF_SEMI 8u
+
/*----- Functions provided ------------------------------------------------*/
/* --- @url_initenc@ --- *
/*----- Functions provided ------------------------------------------------*/
/* --- @url_initenc@ --- *