/*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 Lev Walkin . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * * $Id: urlenc.c,v 1.3 2005/05/25 21:55:10 vlm Exp $ */ #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include /* * Static pointers to encode and decode buffers. */ static char *_sf_urld_buf = NULL; static ssize_t _sf_urld_buflen = 0; static char *_sf_urle_buf = NULL; static int _sf_urle_buflen = 0; char * url_decode(const char *str) { char *buf; char *p; int n; unsigned char c; n = (str ? strlen(str) : 0) + 1; if(n < _sf_urld_buflen) n = _sf_urld_buflen; p = buf = (char *)sf_malloc(n); if(p == NULL) return NULL; /* * If string is NULL, then return empty string. */ if(str == NULL) { if(_sf_urld_buf) free(_sf_urld_buf); _sf_urld_buflen = n; *p = '\0'; return (_sf_urld_buf = buf); } for((void)p; (c = *str); str++, p++) { if(c == '%') { char a, b; if( !(a = str[1]) || !(b = str[2]) ) { /* Incomplete, but valid */ *p = '%'; continue; } if(a >= 'a') a -= 32; if(b >= 'a') b -= 32; if(a >= '0' && a <= '9') c = a - '0'; else if( a >= 'A' && a <= 'F') c = 10 + a - 'A'; else { /* Strange, but valid */ *p = '%'; continue; } c *= 16; if(b >= '0' && b <= '9') c += b - '0'; else if( b >= 'A' && b <= 'F') c += 10 + b - 'A'; else { *p = '%'; /* Strange, but valid */ continue; } str+= 2; } else if(c == '+') { *p = ' '; continue; } *p = c; } *p = '\0'; if(_sf_urld_buf) free(_sf_urld_buf); _sf_urld_buflen = n; return (_sf_urld_buf = buf); } char * url_encode(const char *str) { char *buf; char *p; static char *table="0123456789ABCDEF"; int n; unsigned char c; n = strlen(str?str:"") + 1; if(_sf_urle_buflen > n) n = _sf_urle_buflen; p = buf = (char *)sf_malloc((n + 2) * 3); if(p == NULL) /* ENOMEM? */ return NULL; if(str) { for(; (c=*str); str++) { if( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || strchr("@._", *str) ) { *p++ = *str; continue; } if(c == ' ') { *p++ = '+'; continue; } *p++ = '%'; *p++ = table[ (unsigned char)(c & 0xF0) >> 4]; *p++ = table[ (unsigned char)(c & 0x0F) ]; } /* for */ } /* if(str) */ *p = '\0'; if(_sf_urle_buf) free(_sf_urle_buf); _sf_urle_buflen = n; return (_sf_urle_buf = buf); }