Added URI escape methods and using them in URI parsing.

git-svn-id: http://yate.null.ro/svn/yate/trunk@796 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2006-05-18 15:22:55 +00:00
parent 934c2cc102
commit ceb2ed78ee
3 changed files with 112 additions and 11 deletions

View File

@ -98,6 +98,25 @@ static bool isWordBreak(char c, bool nullOk = false)
return (c == ' ' || c == '\t' || c == '\n' || (nullOk && !c));
}
// Decode a single nibble, return -1 on error
static int hexDecode(char c)
{
if (('0' <= c) && (c <= '9'))
return c - '0';
if (('A' <= c) && (c <= 'F'))
return c - 'A' + 10;
if (('a' <= c) && (c <= 'f'))
return c - 'a' + 10;
return -1;
}
// Encode a single nibble
static inline char hexEncode(char nib)
{
static const char hex[] = "0123456789abcdef";
return hex[nib & 0x0f];
}
StringMatchPrivate::StringMatchPrivate()
{
XDebug(DebugAll,"StringMatchPrivate::StringMatchPrivate() [%p]",this);
@ -781,9 +800,9 @@ ObjList* String::split(char separator, bool emptyOK) const
String String::msgEscape(const char* str, char extraEsc)
{
if (!str)
str = "";
String s;
if (TelEngine::null(str))
return s;
char c;
while ((c=*str++)) {
if (c < ' ' || c == ':' || c == extraEsc) {
@ -799,17 +818,17 @@ String String::msgEscape(const char* str, char extraEsc)
String String::msgUnescape(const char* str, int* errptr, char extraEsc)
{
if (!str)
str = "";
String s;
if (TelEngine::null(str))
return s;
if (extraEsc)
extraEsc += '@';
const char *pos = str;
String s;
char c;
while ((c=*pos++)) {
if (c < ' ') {
if (errptr)
*errptr = (pos-str);
*errptr = (pos-str) - 1;
return s;
}
else if (c == '%') {
@ -818,7 +837,7 @@ String String::msgUnescape(const char* str, int* errptr, char extraEsc)
c -= '@';
else if (c != '%') {
if (errptr)
*errptr = (pos-str);
*errptr = (pos-str) - 1;
return s;
}
}
@ -831,9 +850,9 @@ String String::msgUnescape(const char* str, int* errptr, char extraEsc)
String String::sqlEscape(const char* str, char extraEsc)
{
if (!str)
str = "";
String s;
if (TelEngine::null(str))
return s;
char c;
while ((c=*str++)) {
if (c == '\\' || c == '\'' || c == extraEsc)
@ -843,6 +862,56 @@ String String::sqlEscape(const char* str, char extraEsc)
return s;
}
String String::uriEscape(const char* str, char extraEsc)
{
String s;
if (TelEngine::null(str))
return s;
char c;
while ((c=*str++)) {
if (c <= ' ' || c == '%' || c == '+' || c == '?' || c == '&' || c == extraEsc)
s << '%' << hexEncode(c >> 4) << hexEncode(c);
else
s += c;
}
return s;
}
String String::uriUnescape(const char* str, int* errptr)
{
String s;
if (TelEngine::null(str))
return s;
const char *pos = str;
char c;
while ((c=*pos++)) {
if (c < ' ') {
if (errptr)
*errptr = (pos-str) - 1;
return s;
}
else if (c == '%') {
int hiNibble = hexDecode(*pos++);
if (hiNibble < 0) {
if (errptr)
*errptr = (pos-str) - 1;
return s;
}
int loNibble = hexDecode(*pos++);
if (loNibble < 0) {
if (errptr)
*errptr = (pos-str) - 1;
return s;
}
c = ((hiNibble << 4) | loNibble) & 0xff;
}
s += c;
}
if (errptr)
*errptr = -1;
return s;
}
unsigned int String::hash() const
{
if (m_hash == INIT_HASH)

View File

@ -113,8 +113,8 @@ void URI::parse() const
m_proto = tmp.matchString(1).toLower();
m_proto = m_proto.substr(0,m_proto.length()-1);
m_user = tmp.matchString(2);
m_user = m_user.substr(0,m_user.length()-1);
m_host = tmp.matchString(3).toLower();
m_user = m_user.substr(0,m_user.length()-1).uriUnescape();
m_host = tmp.matchString(3).uriUnescape().toLower();
tmp = tmp.matchString(4);
tmp >> ":" >> m_port;
DDebug("URI",DebugAll,"desc='%s' proto='%s' user='%s' host='%s' port=%d [%p]",

View File

@ -1573,6 +1573,38 @@ public:
inline String sqlEscape(char extraEsc = 0) const
{ return sqlEscape(c_str(),extraEsc); }
/**
* Create an escaped string suitable for use in URIs
* @param str String to convert to escaped format
* @param extraEsc Character to escape other than the default ones
* @return The string with special characters escaped
*/
static String uriEscape(const char* str, char extraEsc = 0);
/**
* Create an escaped string suitable for use in URI
* @param extraEsc Character to escape other than the default ones
* @return The string with special characters escaped
*/
inline String uriEscape(char extraEsc = 0) const
{ return uriEscape(c_str(),extraEsc); }
/**
* Decode an URI escaped string back to its raw form
* @param str String to convert to unescaped format
* @param errptr Pointer to an integer to receive the place of 1st error
* @return The string with special characters unescaped
*/
static String uriUnescape(const char* str, int* errptr = 0);
/**
* Decode an URI escaped string back to its raw form
* @param errptr Pointer to an integer to receive the place of 1st error
* @return The string with special characters unescaped
*/
inline String uriUnescape(int* errptr = 0) const
{ return uriUnescape(c_str(),errptr); }
protected:
/**
* Called whenever the value changed (except in constructors).