Skip to content

Commit

Permalink
Consistently unescape XML attributes when loading scenario
Browse files Browse the repository at this point in the history
This changes the behaviour of `xp_get_string()` in order to
systematically unescape the returned values, as other XML parsers do.
The custom unescaping in the handling of the `<ereg>` element has been
removed as it is now unneeded.

This will make it possible to e.g. compare strings that contain special
XML characters using `<strcmp>`.

A regression test case has been added to highlight the problem.

SIPp#458
  • Loading branch information
nud committed May 6, 2020
1 parent 4dad7f2 commit 4ef839d
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 14 deletions.
22 changes: 22 additions & 0 deletions regress/github-#0458/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
# This regression test is a part of SIPp.
. "`dirname "$0"`/../functions"; init

sippfg -m 1 -sf uas.xml -p 5070 >/dev/null 2>&1 &
job=$!

sippfg -m 1 -sf uac.xml 127.0.0.1:5070 \
-trace_err -error_file err.log \
-timeout 4 -timeout_error >/dev/null 2>&1
status=$?
wait $job || status=1

if test $status -eq 0; then
ok
else
if grep -q 'Matching Error' err.log; then
fail "matching error - escaping?"
else
fail "unknown failure"
fi
fi
62 changes: 62 additions & 0 deletions regress/github-#0458/uac.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario>
<send retrans="500" start_txn="invite">
<![CDATA[
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: "Tom Jones" <sip:[email protected]>;tag=[pid]SIPpTag00[call_number]
To: "Fromage" <sip:[email protected]>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: sip:sipp@[local_ip]:[local_port]
Content-Length: 0
]]>
</send>

<recv response="404" response_txn="invite">
<action>
<ereg regexp="(&quot;[^&quot;]*&quot; &lt;[^&gt;]*&gt;)" search_in="hdr" header="To:" assign_to="var"/>
</action>
</recv>
<Reference variables="var"/>

<send ack_txn="invite">
<![CDATA[
ACK [next_url] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
[routes]
From: sip:[service]@[local_ip]:[local_port];tag=[pid]SIPpTag00[call_number]
To: sip:[service]@[remote_ip]:[remote_port][peer_tag_param]
Call-ID: [call_id]
CSeq: [cseq] ACK
Contact: sip:[service]@[local_ip]:[local_port]
Content-Length: 0
]]>
</send>

<!--
If attribute escaping handling is correct in the scenario loading, then the
test below will work. If it doesn't, then it will fail because of the XML
entities.
-->
<nop>
<action>
<strcmp assign_to="1" variable="var" value="&quot;Fromage&quot; &lt;sip:[email protected]&gt;"/>
<test assign_to="result" variable="1" compare="equal" value="0" /> <!-- If strcmp is successful, it returns 0 -->
</action>
</nop>

<nop condexec="result" condexec_inverse="true">
<action>
<warning message="Matching Error: '[$var]' != '&quot;Fromage&quot; &lt;sip:[email protected]&gt;'"/>
<exec int_cmd="stop_now" />
</action>
</nop>

<timewait milliseconds="500"/>
</scenario>
22 changes: 22 additions & 0 deletions regress/github-#0458/uas.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario>
<recv request="INVITE"/>

<send retrans="500">
<![CDATA[
SIP/2.0 404 Not Found
[last_Via:]
[last_From:]
[last_To:];tag=[pid]SIPpTag00[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: sip:sipp@[local_ip]:[local_port]
Content-Length: 0
]]>
</send>

<recv request="ACK"/>

<timewait milliseconds="500"/>
</scenario>
21 changes: 7 additions & 14 deletions src/scenario.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,16 @@ static char* xp_get_keyword_value(const char *name)
static char* xp_get_string(const char *name, const char *what)
{
const char *ptr;
char *unescaped;

if (!(ptr = xp_get_value(name))) {
ERROR("%s is missing the required '%s' parameter.", what, name);
}

return strdup(ptr);
unescaped = new char[strlen(ptr)+1];
xp_unescape(ptr, unescaped);

return unescaped;
}

static double xp_get_double(const char *name, const char *what)
Expand Down Expand Up @@ -1344,7 +1348,6 @@ void scenario::parseAction(CActions *actions)
{
char * actionElem;
unsigned int recvScenarioLen = 0;
char * currentRegExp = NULL;
char ** currentTabVarName = NULL;
int currentNbVarNames;
int sub_currentNbVarId;
Expand All @@ -1357,19 +1360,13 @@ void scenario::parseAction(CActions *actions)
if(!strcmp(actionElem, "ereg")) {
ptr = xp_get_string("regexp", "ereg");

// keeping regexp expression in memory
if(currentRegExp != NULL)
delete[] currentRegExp;
currentRegExp = new char[strlen(ptr)+1];
xp_unescape(ptr, currentRegExp);
tmpAction->setActionType(CAction::E_AT_ASSIGN_FROM_REGEXP);

// warning - although these are detected for both msg and hdr
// they are only implemented for search_in="hdr"
tmpAction->setCaseIndep(xp_get_bool("case_indep", "ereg", false));
tmpAction->setHeadersOnly(xp_get_bool("start_line", "ereg", false));

free(ptr);
if ((cptr = xp_get_value("search_in"))) {
tmpAction->setOccurrence(1);

Expand Down Expand Up @@ -1421,7 +1418,7 @@ void scenario::parseAction(CActions *actions)
int varId = get_var(currentTabVarName[0], "assign_to");
tmpAction->setVarId(varId);

tmpAction->setRegExp(currentRegExp);
tmpAction->setRegExp(ptr);
if (currentNbVarNames > 1 ) {
sub_currentNbVarId = currentNbVarNames - 1 ;
tmpAction->setNbSubVarId(sub_currentNbVarId);
Expand All @@ -1433,11 +1430,7 @@ void scenario::parseAction(CActions *actions)
}

freeStringTable(currentTabVarName, currentNbVarNames);

if(currentRegExp != NULL) {
delete[] currentRegExp;
}
currentRegExp = NULL;
free(ptr);
} /* end !strcmp(actionElem, "ereg") */ else if(!strcmp(actionElem, "log")) {
ptr = xp_get_string("message", "log");
tmpAction->setMessage(ptr);
Expand Down

0 comments on commit 4ef839d

Please sign in to comment.