core: fixing get_header_keyvalue. issue 0000024

https://bugtracker.iptel.org/view.php?id=24
sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent 0bcdd93bcf
commit 1e3f874833

@ -801,116 +801,145 @@ string get_header_keyvalue(const string& param_hdr, const string& name) {
string get_header_keyvalue_single(const string& param_hdr, const string& name) {
// ugly, but we need escaping
#define ST_FINDKEY 0
#define ST_FK_ESC 1
#define ST_CMPKEY 2
#define ST_SRCHEND 3
#define ST_SE_VAL 4
#define ST_SE_ESC 5
size_t p=0, s_begin=0, corr=0,
#define ST_FINDBGN 0
#define ST_FB_ESC 1
#define ST_BEGINKEY 2
#define ST_CMPKEY 3
#define ST_FINDEQ 4
#define ST_FINDVAL 5
#define ST_VALUE 6
#define ST_VAL_ESC 7
size_t p=0, k_begin=0, corr=0,
v_begin=0, v_end=0;
unsigned int st = ST_FINDKEY;
char last = ' ';
char esc_char = ' ';
unsigned int st = ST_BEGINKEY;
while (p<param_hdr.length()) {
while (p<param_hdr.length() && !v_end) {
char curr = param_hdr[p];
// DBG("curr %c, st=%d\n", curr, st);
switch(st) {
default:
case ST_FINDKEY: {
switch(curr){
case '"':
case '\'':
st = ST_FK_ESC;
break;
default:
if (curr==name[0]) {
st = ST_CMPKEY;
s_begin = p;
corr = 1;
}
}
p++;
}; break;
case ST_FK_ESC: {
switch(curr){
case '"':
case '\'':
st = ST_FINDKEY;
break;
default:
break;
case ST_FINDBGN: {
switch(curr) {
case '"':
case '\'':
{
st = ST_FB_ESC;
esc_char = curr;
} break;
case ';':
st = ST_BEGINKEY;
break;
default: break;
} break;
} break;
case ST_FB_ESC: {
if (curr == esc_char && last != '\\') {
st = ST_FINDBGN;
}
} break;
case ST_BEGINKEY: {
switch (curr) {
case ' ': // spaces before the key
case '\t':
break;
default:
if (curr==name[0]) {
st = ST_CMPKEY;
k_begin = p;
corr = 1;
}
p++;
}; break;
}
} break;
case ST_CMPKEY: {
if (corr==name.length()) {
if (curr=='=') {
st = ST_SRCHEND;
v_begin=++p;
} else {
p=s_begin+1;
st = ST_FINDKEY;
corr=0;
}
} else {
if (curr==name[corr]) {
p++;
corr++;
if (corr == name.length()) {
st = ST_FINDEQ;
}
} else {
st = ST_FINDKEY;
st = ST_FINDBGN;
corr=0;
p=s_begin+1;
p=k_begin; // will continue searching one after k_begin
}
} break;
case ST_FINDEQ: {
switch (curr) {
case ' ':
case '\t':
break;
case '=':
st = ST_FINDVAL; break;
default: {
st = ST_FINDBGN;
corr=0;
p=k_begin; // will continue searching one after k_begin
} break;
}
}; break;
case ST_SRCHEND: {
switch(curr){
case '"':
case '\'':
v_begin++;
st = ST_SE_ESC;
break;
default:
st = ST_SE_VAL;
}
p++;
v_end = p;
}; break;
case ST_SE_VAL: {
if (curr==';')
p = param_hdr.length();
else {
} break;
case ST_FINDVAL: {
switch (curr) {
case ' ':
case '\t':
break;
case '"':
case '\'': {
st = ST_VAL_ESC;
esc_char = curr;
v_begin=p;
} break;
default:
st = ST_VALUE;
v_begin=p;
}
} break;
case ST_VALUE: {
switch (curr) {
case '"':
case '\'': {
st = ST_VAL_ESC;
esc_char = curr;
} break;
case ';':
v_end = p;
p++;
break;
default: break;
}
}; break;
case ST_SE_ESC: {
switch(curr){
case '"':
case '\'':
p = param_hdr.length();
break;
default:
v_end = p;
p++;
}
}; break;
} break;
case ST_VAL_ESC: {
if (curr == esc_char && last != '\\') {
st = ST_VALUE;
}
} break;
}
p++;
last = curr;
}
if (!v_end && (st == ST_VALUE || st == ST_VAL_ESC))
v_end = p;
if (v_begin && v_end)
return param_hdr.substr(v_begin, v_end-v_begin+1);
else if (v_begin && (p==param_hdr.length()))
return param_hdr.substr(v_begin);
else
if (v_begin && v_end) {
if ((v_end - v_begin > 1) &&
(param_hdr[v_begin] == param_hdr[v_end-1]) &&
((param_hdr[v_begin] == '\'') || (param_hdr[v_begin] == '"')))
return param_hdr.substr(v_begin+1, v_end-v_begin-2); // whole value quoted
return param_hdr.substr(v_begin, v_end-v_begin);
} else
return "";
}

@ -41,7 +41,20 @@ FCTMF_SUITE_BGN(test_headers) {
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval;myotherfunkykey=myval", "P-My-Test", true), "mykey") == "myval" );
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval;myotherfunkykey=myval2", "P-My-Test", true), "myotherfunkykey") == "myval2" );
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval;myotherfunkykey=myval;andsomemore", "P-My-Test", true), "mykey") == "myval" );
fct_chk(get_header_keyvalue(getHeader("P-App-Param: product_id=1;productid=1;bla=blub ", "P-App-Param"), "product_id") == "1");
fct_chk(get_header_keyvalue(getHeader("P-App-Param: product_id=11;productid=1;bla=blub ", "P-App-Param"), "product_id") == "11");
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval; myotherfunkykey=myval;andsomemore", "P-My-Test", true), "mykey") == "myval" );
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval; myotherfunkykey= myval;andsomemore", "P-My-Test", true), "myotherfunkykey") == "myval" );
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval; myotherfunkykey= \"myval\";andsomemore", "P-My-Test", true), "myotherfunkykey") == "myval" );
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval; myotherfunkykey='myval';andsomemore", "P-My-Test", true), "myotherfunkykey") == "myval" );
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval; myotherfunkykey= '';andsomemore", "P-My-Test", true), "myotherfunkykey") == "");
fct_chk(get_header_keyvalue(getHeader("P-My-Test: mykey=myval; myotherfunkykey= 'test \\' escaped';andsomemore", "P-My-Test", true), "test \\' escaped") == "");
} FCT_TEST_END();

Loading…
Cancel
Save