summaryrefslogtreecommitdiff
path: root/common/url.c
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-03-11 17:17:15 +0100
committerStef Walter <stefw@gnome.org>2013-03-15 18:18:47 +0100
commit48004b92d4c65080ac71f6a48297abd4d83dfdcb (patch)
tree09c1f5051e5ca59d5465344e532e2e3b85b48648 /common/url.c
parent06bf3da80eb780621e0f1eb0ab8d4716ed7b3478 (diff)
downloadp11-kit-48004b92d4c65080ac71f6a48297abd4d83dfdcb.tar.gz
url: Split out the URL encoding and decoding functions
We want to use these as the format for encoding binary data in our PKCS#11 attribute persistence https://bugs.freedesktop.org/show_bug.cgi?id=62156
Diffstat (limited to 'common/url.c')
-rw-r--r--common/url.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/common/url.c b/common/url.c
new file mode 100644
index 0000000..6ccf74d
--- /dev/null
+++ b/common/url.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "debug.h"
+#include "url.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+const static char HEX_CHARS[] = "0123456789abcdef";
+
+unsigned char *
+p11_url_decode (const char *value,
+ const char *end,
+ const char *skip,
+ size_t *length)
+{
+ char *a, *b;
+ unsigned char *result, *p;
+
+ assert (value <= end);
+ assert (skip != NULL);
+
+ /* String can only get shorter */
+ result = malloc ((end - value) + 1);
+ return_val_if_fail (result != NULL, NULL);
+
+ /* Now loop through looking for escapes */
+ p = result;
+ while (value != end) {
+ /*
+ * A percent sign followed by two hex digits means
+ * that the digits represent an escaped character.
+ */
+ if (*value == '%') {
+ value++;
+ if (value + 2 > end) {
+ free (result);
+ return NULL;
+ }
+ a = strchr (HEX_CHARS, tolower (value[0]));
+ b = strchr (HEX_CHARS, tolower (value[1]));
+ if (!a || !b) {
+ free (result);
+ return NULL;
+ }
+ *p = (a - HEX_CHARS) << 4;
+ *(p++) |= (b - HEX_CHARS);
+ value += 2;
+
+ /* Ignore whitespace characters */
+ } else if (strchr (skip, *value)) {
+ value++;
+
+ /* A different character */
+ } else {
+ *(p++) = *(value++);
+ }
+ }
+
+ /* Null terminate string, in case its a string */
+ *p = 0;
+
+ if (length)
+ *length = p - result;
+ return result;
+}
+
+char *
+p11_url_encode (const unsigned char *value,
+ const unsigned char *end,
+ const char *verbatim,
+ size_t *length)
+{
+ char *p;
+ char *result;
+
+ assert (value <= end);
+
+ /* Just allocate for worst case */
+ result = malloc (((end - value) * 3) + 1);
+ return_val_if_fail (result != NULL, NULL);
+
+ /* Now loop through looking for escapes */
+ p = result;
+ while (value != end) {
+
+ /* These characters we let through verbatim */
+ if (*value && strchr (verbatim, *value) != NULL) {
+ *(p++) = *(value++);
+
+ /* All others get encoded */
+ } else {
+ *(p++) = '%';
+ *(p++) = HEX_CHARS[((unsigned char)*value) >> 4];
+ *(p++) = HEX_CHARS[((unsigned char)*value) & 0x0F];
+ ++value;
+ }
+ }
+
+ *p = 0;
+ if (length)
+ *length = p - result;
+ return result;
+}