Commit 0a9ac826f38e4d63c651fba939a54992d7fbfb5d
1 parent
ff433330
Exists in
master
and in
3 other branches
Fixing 'escape' problem in winldap query.
Showing
3 changed files
with
92 additions
and
1 deletions
Show diff stats
src/core/util.c
| ... | ... | @@ -714,3 +714,83 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s |
| 714 | 714 | |
| 715 | 715 | return getsockname(hSession->sock, addr, addrlen); |
| 716 | 716 | } |
| 717 | + | |
| 718 | +static int xdigit_value(const char scanner) | |
| 719 | +{ | |
| 720 | + | |
| 721 | + if(scanner >= '0' && scanner <= '9') { | |
| 722 | + return scanner - '0'; | |
| 723 | + } | |
| 724 | + | |
| 725 | + if(scanner >= 'A' && scanner <= 'F') { | |
| 726 | + return 10 + (scanner - 'A'); | |
| 727 | + } | |
| 728 | + | |
| 729 | + if(scanner >= 'a' && scanner <= 'f') { | |
| 730 | + return 10 + (scanner - 'a'); | |
| 731 | + } | |
| 732 | + | |
| 733 | + return -1; | |
| 734 | +} | |
| 735 | + | |
| 736 | +static int unescape_character(const char *scanner) | |
| 737 | +{ | |
| 738 | + | |
| 739 | + int first_digit = xdigit_value(*scanner++); | |
| 740 | + int second_digit = xdigit_value(*scanner++); | |
| 741 | + | |
| 742 | + if (first_digit < 0) | |
| 743 | + return -1; | |
| 744 | + | |
| 745 | + if (second_digit < 0) | |
| 746 | + return -1; | |
| 747 | + | |
| 748 | + return (first_digit << 4) | second_digit; | |
| 749 | + | |
| 750 | +} | |
| 751 | + | |
| 752 | +char * lib3270_unescape(const char *text) | |
| 753 | +{ | |
| 754 | + if(!text) | |
| 755 | + return NULL; | |
| 756 | + | |
| 757 | + size_t sz = strlen(text); | |
| 758 | + char * outString = lib3270_malloc(sz+1); | |
| 759 | + char * dst = outString; | |
| 760 | + const char * src = text; | |
| 761 | + char * ptr = strchr(src,'%'); | |
| 762 | + | |
| 763 | + memset(outString,0,sz+1); | |
| 764 | + | |
| 765 | + while(ptr) | |
| 766 | + { | |
| 767 | + if(ptr[1] == '%') | |
| 768 | + { | |
| 769 | + src = ptr+2; | |
| 770 | + } | |
| 771 | + else | |
| 772 | + { | |
| 773 | + size_t sz = (ptr - src); | |
| 774 | + memcpy(dst,src,sz); | |
| 775 | + dst += sz; | |
| 776 | + | |
| 777 | + int chr = unescape_character(ptr+1); | |
| 778 | + if(chr < 0) | |
| 779 | + { | |
| 780 | + *(dst++) = '?'; | |
| 781 | + } | |
| 782 | + else | |
| 783 | + { | |
| 784 | + *(dst++) = (char) chr; | |
| 785 | + } | |
| 786 | + | |
| 787 | + src += (sz+3); | |
| 788 | + } | |
| 789 | + | |
| 790 | + ptr = strchr(src,'%'); | |
| 791 | + } | |
| 792 | + | |
| 793 | + strcpy(dst,src); | |
| 794 | + | |
| 795 | + return outString; | |
| 796 | +} | ... | ... |
src/include/utilc.h
| ... | ... | @@ -59,3 +59,13 @@ LIB3270_INTERNAL void rpf_init(rpf_t *r); |
| 59 | 59 | LIB3270_INTERNAL void rpf_reset(rpf_t *r); |
| 60 | 60 | LIB3270_INTERNAL void rpf(rpf_t *r, char *fmt, ...) LIB3270_GNUC_FORMAT(2, 3); |
| 61 | 61 | LIB3270_INTERNAL void rpf_free(rpf_t *r); |
| 62 | + | |
| 63 | +/** | |
| 64 | + * @brief "unescape" text (Replaces %value for corresponding character). | |
| 65 | + * | |
| 66 | + * @param text Text to convert. | |
| 67 | + * | |
| 68 | + * @return Converted string (release it with g_free). | |
| 69 | + * | |
| 70 | + */ | |
| 71 | +LIB3270_INTERNAL char * lib3270_unescape(const char *text); | ... | ... |
src/ssl/windows/ldap.c
| ... | ... | @@ -40,6 +40,7 @@ |
| 40 | 40 | |
| 41 | 41 | #include "private.h" |
| 42 | 42 | #include <winldap.h> |
| 43 | +#include <utilc.h> | |
| 43 | 44 | |
| 44 | 45 | # ifndef LDAP_VENDOR_NAME |
| 45 | 46 | # 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 |
| 94 | 95 | |
| 95 | 96 | // Strip query. |
| 96 | 97 | |
| 97 | - lib3270_autoptr(char) urldup = strdup(consturl); | |
| 98 | + lib3270_autoptr(char) urldup = lib3270_unescape(consturl); | |
| 98 | 99 | |
| 99 | 100 | char * url = urldup+7; |
| 100 | 101 | char * base = strchr(url,'/'); | ... | ... |