/* -*-c-*-
*
- * $Id: url.c,v 1.1 1999/06/01 09:49:48 mdw Exp $
+ * $Id: url.c,v 1.5 2004/04/08 01:36:13 mdw Exp $
*
* Parsing and construction of url-encoded name/value pairs
*
* (c) 1999 Straylight/Edgeware
*/
-/*----- Licensing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of the mLib utilities library.
*
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
- *
+ *
* mLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Library General Public
* License along with mLib; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: url.c,v $
- * Revision 1.1 1999/06/01 09:49:48 mdw
- * New files for url-encoding and decoding.
- *
- */
-
/*----- Header files ------------------------------------------------------*/
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
* Use: Initializes a URL encoding context.
*/
-void url_initenc(url_ectx *ctx)
-{
- ctx->f = 0;
-}
+void url_initenc(url_ectx *ctx) { ctx->f = 0; }
/* --- @encode@ --- *
*
- * Arguments: @dstr *d@ = pointer to output string
+ * Arguments: @url_ectx *ctx@ = encoding context
+ * @dstr *d@ = pointer to output string
* @const char *p@ = pointer to thing to encode
*
* Returns: ---
* Use: Encodes the input string into the output string.
*/
-static void encode(dstr *d, const char *p)
+static void encode(url_ectx *ctx, dstr *d, const char *p)
{
while (*p) {
switch (*p) {
case ' ':
DPUTC(d, '+');
- break;
+ break;
default:
- if (*p >= 33 && *p < 127)
- DPUTC(d, *p);
- else
- case '&':
+ if ((ctx->f & URLF_LAX) || isalnum((unsigned char)*p))
+ goto safe;
+ else
+ goto unsafe;
+ case '/':
+ case '~':
+ if (ctx->f & URLF_STRICT)
+ goto unsafe;
+ case '-':
+ case '.':
+ case '_':
+ safe:
+ DPUTC(d, *p);
+ break;
+ unsafe:
case '+':
- case '=':
case '%':
+ case '=':
+ case '&':
+ case ';':
dstr_putf(d, "%%%02x", *p);
- break;
+ break;
}
p++;
}
void url_enc(url_ectx *ctx, dstr *d, const char *name, const char *value)
{
if (ctx->f & URLF_SEP)
- DPUTC(d, '&');
- encode(d, name);
+ DPUTC(d, (ctx->f & URLF_SEMI) ? ';' : '&');
+ encode(ctx, d, name);
DPUTC(d, '=');
- encode(d, value);
+ encode(ctx, d, value);
DPUTZ(d);
ctx->f |= URLF_SEP;
}
* 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; }
/* --- @decode@ --- *
*
- * 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
*
* 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)
{
if (!*p)
return (0);
case '=':
if (eq)
return (p);
- DPUTC(d, *p);
- break;
+ goto boring;
+ case ';':
+ if (ctx->f & URLF_SEMI)
+ return (p);
+ goto boring;
case 0:
case '&':
return (p);
}
}
default:
+ boring:
DPUTC(d, *p);
break;
}
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++;
goto again;
}
p++;
- if ((p = decode(v, p, 0)) == 0)
+ if ((p = decode(ctx, v, p, 0)) == 0)
return (0);
DPUTZ(n);
DPUTZ(v);