X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Furi.c;h=efa11bf4df23af6123388ba8057023643a22149a;hp=326aaa202eb834a5c04df46247491f892dfe8750;hb=5d2037ccd6b74ec67f662a83477820792b7172b3;hpb=42bf8d7d53e41f6165e0eb889a7377d3482aeabd diff --git a/src/uri.c b/src/uri.c index 326aaa2..efa11bf 100644 --- a/src/uri.c +++ b/src/uri.c @@ -1,11 +1,14 @@ /* This file is part of the YAZ toolkit. - * Copyright (C) 1995-2009 Index Data + * Copyright (C) Index Data * See the file LICENSE for details. */ /** - * \file srwutil.c - * \brief Implements SRW/SRU utilities. + * \file uri.c + * \brief Implements URI utilities. */ +#if HAVE_CONFIG_H +#include +#endif #include #include @@ -20,16 +23,14 @@ static int hex_digit (int ch) return ch - 'a'+10; else if (ch >= 'A' && ch <= 'F') return ch - 'A'+10; - return 0; + return -1; } -void encode_uri_char(char *dst, char ch) +static void encode_uri_char(char *dst, char ch) { - if (ch == ' ') - strcpy(dst, "+"); /* mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */ - else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || - (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch)) + if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || + (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch)) { dst[0] = ch; dst[1] = '\0'; @@ -41,31 +42,78 @@ void encode_uri_char(char *dst, char ch) } } +void yaz_encode_uri_component(char *dst, const char *uri) +{ + for (; *uri; uri++) + { + encode_uri_char(dst, *uri); + dst += strlen(dst); + } + *dst = '\0'; +} + +static unsigned char decode_uri_char(const char *path, size_t *len) +{ + unsigned char ch; + if (*path == '+') + { + ch = ' '; + *len = 1; + } + else if (*path == '%' && *len >= 3) + { + int d1 = hex_digit(path[1]); + int d2 = hex_digit(path[2]); + if (d1 >= 0 && d2 >= 0) + { + ch = d1 * 16 + d2; + *len = 3; + } + else + { + ch = *path; + *len = 1; + } + } + else + { + ch = *path; + *len = 1; + } + return ch; +} + +void yaz_decode_uri_component(char *dst, const char *uri, size_t len) +{ + while (len) + { + size_t sz = len; + *dst++ = decode_uri_char(uri, &sz); + uri += sz; + len = len - sz; + } + *dst = '\0'; +} + void yaz_array_to_uri(char **path, ODR o, char **name, char **value) { size_t i, szp = 0, sz = 1; for(i = 0; name[i]; i++) sz += strlen(name[i]) + 3 + strlen(value[i]) * 3; *path = (char *) odr_malloc(o, sz); - + for(i = 0; name[i]; i++) { - size_t j, ilen; + size_t ilen; if (i) (*path)[szp++] = '&'; ilen = strlen(name[i]); memcpy(*path+szp, name[i], ilen); szp += ilen; (*path)[szp++] = '='; - for (j = 0; value[i][j]; j++) - { - size_t vlen; - char vstr[5]; - encode_uri_char(vstr, value[i][j]); - vlen = strlen(vstr); - memcpy(*path+szp, vstr, vlen); - szp += vlen; - } + + yaz_encode_uri_component(*path + szp, value[i]); + szp += strlen(*path + szp); } (*path)[szp] = '\0'; } @@ -84,98 +132,54 @@ int yaz_uri_to_array(const char *path, ODR o, char ***name, char ***val) { cp++; no++; + while (*cp && *cp != '=' && *cp != '&') + { + /* check that x-form names looks sane */ + if (*cp <= ' ' || *cp >= 127) + return 0; + cp++; + } } *name = (char **) odr_malloc(o, no * sizeof(char*)); *val = (char **) odr_malloc(o, no * sizeof(char*)); for (no = 0; *path; no++) { - const char *p1 = strchr(path, '='); - size_t i = 0; - char *ret; - if (!p1) + while (*path == '&') + path++; + if (!*path) break; - (*name)[no] = (char *) odr_malloc(o, (p1-path)+1); - memcpy((*name)[no], path, p1-path); - (*name)[no][p1-path] = '\0'; + for (cp = path; *cp && *cp != '=' && *cp != '&'; cp++) + ; - path = p1 + 1; - p1 = strchr(path, '&'); - if (!p1) - p1 = strlen(path) + path; - (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1); - while (*path && *path != '&') - { - if (*path == '+') - { - ret[i++] = ' '; - path++; - } - else if (*path == '%' && path[1] && path[2]) - { - ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]); - path = path + 3; - } - else - ret[i++] = *path++; - } - ret[i] = '\0'; - - if (*path) - path++; - } - (*name)[no] = 0; - (*val)[no] = 0; - return no; -} - -char *yaz_uri_val(const char *path, const char *name, ODR o) -{ - size_t nlen = strlen(name); - if (*path != '?') - return 0; - path++; - while (path && *path) - { - const char *p1 = strchr(path, '='); - if (!p1) - break; - if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen)) + (*name)[no] = odr_strdupn(o, path, cp - path); + path = cp; + if (*path == '=') { size_t i = 0; char *ret; - - path = p1 + 1; - p1 = strchr(path, '&'); - if (!p1) - p1 = strlen(path) + path; - ret = (char *) odr_malloc(o, p1 - path + 1); + path++; + for (cp = path; *cp && *cp != '&'; cp++) + ; + (*val)[no] = ret = (char *) odr_malloc(o, cp - path + 1); while (*path && *path != '&') { - if (*path == '+') - { - ret[i++] = ' '; - path++; - } - else if (*path == '%' && path[1] && path[2]) - { - ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]); - path = path + 3; - } - else - ret[i++] = *path++; + size_t l = 3; + ret[i++] = decode_uri_char(path, &l); + path += l; } ret[i] = '\0'; - return ret; } - path = strchr(p1, '&'); - if (path) - path++; + else + (*val)[no] = odr_strdup(o, ""); } - return 0; + (*name)[no] = 0; + (*val)[no] = 0; + return no; } + /* * Local variables: * c-basic-offset: 4