diff --git a/src/core/util.c b/src/core/util.c index d6a90b1..c109860 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -714,3 +714,83 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s return getsockname(hSession->sock, addr, addrlen); } + +static int xdigit_value(const char scanner) +{ + + if(scanner >= '0' && scanner <= '9') { + return scanner - '0'; + } + + if(scanner >= 'A' && scanner <= 'F') { + return 10 + (scanner - 'A'); + } + + if(scanner >= 'a' && scanner <= 'f') { + return 10 + (scanner - 'a'); + } + + return -1; +} + +static int unescape_character(const char *scanner) +{ + + int first_digit = xdigit_value(*scanner++); + int second_digit = xdigit_value(*scanner++); + + if (first_digit < 0) + return -1; + + if (second_digit < 0) + return -1; + + return (first_digit << 4) | second_digit; + +} + +char * lib3270_unescape(const char *text) +{ + if(!text) + return NULL; + + size_t sz = strlen(text); + char * outString = lib3270_malloc(sz+1); + char * dst = outString; + const char * src = text; + char * ptr = strchr(src,'%'); + + memset(outString,0,sz+1); + + while(ptr) + { + if(ptr[1] == '%') + { + src = ptr+2; + } + else + { + size_t sz = (ptr - src); + memcpy(dst,src,sz); + dst += sz; + + int chr = unescape_character(ptr+1); + if(chr < 0) + { + *(dst++) = '?'; + } + else + { + *(dst++) = (char) chr; + } + + src += (sz+3); + } + + ptr = strchr(src,'%'); + } + + strcpy(dst,src); + + return outString; +} diff --git a/src/include/utilc.h b/src/include/utilc.h index 5e737a6..2372547 100644 --- a/src/include/utilc.h +++ b/src/include/utilc.h @@ -59,3 +59,13 @@ LIB3270_INTERNAL void rpf_init(rpf_t *r); LIB3270_INTERNAL void rpf_reset(rpf_t *r); LIB3270_INTERNAL void rpf(rpf_t *r, char *fmt, ...) LIB3270_GNUC_FORMAT(2, 3); LIB3270_INTERNAL void rpf_free(rpf_t *r); + +/** + * @brief "unescape" text (Replaces %value for corresponding character). + * + * @param text Text to convert. + * + * @return Converted string (release it with g_free). + * + */ +LIB3270_INTERNAL char * lib3270_unescape(const char *text); diff --git a/src/ssl/windows/ldap.c b/src/ssl/windows/ldap.c index 6863fcb..2aa6b95 100644 --- a/src/ssl/windows/ldap.c +++ b/src/ssl/windows/ldap.c @@ -40,6 +40,7 @@ #include "private.h" #include +#include # ifndef LDAP_VENDOR_NAME # error Your Platform SDK is NOT sufficient for LDAP support! \ @@ -94,7 +95,7 @@ X509_CRL * get_crl_using_ldap(H3270 *hSession, SSL_ERROR_MESSAGE * message, cons // Strip query. - lib3270_autoptr(char) urldup = strdup(consturl); + lib3270_autoptr(char) urldup = lib3270_unescape(consturl); char * url = urldup+7; char * base = strchr(url,'/'); -- libgit2 0.21.2