summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2005-11-22 23:51:50 +0000
committerBenny Prijono <bennylp@teluu.com>2005-11-22 23:51:50 +0000
commitbf364b7c7deabe95dea0cf62180cdbf36c7c2031 (patch)
tree4e001db192608b4058476a8f686e25ab674d8676
parent2ddb744528ad991173650a2b6e3ff20796b3a748 (diff)
More optimizations for msg parser etc.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@77 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib-util/build/pjlib_util.dsp2
-rw-r--r--pjlib-util/include/pjlib-util/scanner.h79
-rw-r--r--pjlib-util/src/pjlib-util/scanner.c166
-rw-r--r--pjlib-util/src/pjlib-util/xml.c2
-rw-r--r--pjlib/include/pj/string.h24
-rw-r--r--pjlib/include/pj/string_i.h47
-rw-r--r--pjlib/src/pjlib-test/string.c1
-rw-r--r--pjsip/build/pjsip_core.dsp2
-rw-r--r--pjsip/include/pjsip/print_util.h62
-rw-r--r--pjsip/include/pjsip/sip_parser.h6
-rw-r--r--pjsip/src/pjsip/sip_endpoint.c4
-rw-r--r--pjsip/src/pjsip/sip_parser.c221
-rw-r--r--pjsip/src/pjsip/sip_uri.c30
-rw-r--r--pjsip/src/test-pjsip/msg.c16
-rw-r--r--pjsip/src/test-pjsip/test.c4
15 files changed, 369 insertions, 297 deletions
diff --git a/pjlib-util/build/pjlib_util.dsp b/pjlib-util/build/pjlib_util.dsp
index 5497aff9..692e32d8 100644
--- a/pjlib-util/build/pjlib_util.dsp
+++ b/pjlib-util/build/pjlib_util.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Oy /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
diff --git a/pjlib-util/include/pjlib-util/scanner.h b/pjlib-util/include/pjlib-util/scanner.h
index 1a4a69ef..b8f8f761 100644
--- a/pjlib-util/include/pjlib-util/scanner.h
+++ b/pjlib-util/include/pjlib-util/scanner.h
@@ -193,12 +193,12 @@ typedef void (*pj_syn_err_func_ptr)(struct pj_scanner *scanner);
*/
typedef struct pj_scanner
{
- char *begin; /**< Start of input buffer. */
- char *end; /**< End of input buffer. */
- char *curptr; /**< Current pointer. */
- int line; /**< Current line. */
- int col; /**< Current column. */
- int skip_ws; /**< Skip whitespace flag. */
+ char *begin; /**< Start of input buffer. */
+ char *end; /**< End of input buffer. */
+ char *curptr; /**< Current pointer. */
+ int line; /**< Current line. */
+ char *start_line; /**< Where current line starts. */
+ int skip_ws; /**< Skip whitespace flag. */
pj_syn_err_func_ptr callback; /**< Syntax error callback. */
} pj_scanner;
@@ -210,8 +210,8 @@ typedef struct pj_scanner
typedef struct pj_scan_state
{
char *curptr; /**< Current scanner's pointer. */
- int line; /**< Current line. */
- int col; /**< Current column. */
+ int line; /**< Current line. */
+ char *start_line; /**< Start of current line. */
} pj_scan_state;
@@ -325,7 +325,8 @@ PJ_DECL(void) pj_scan_get( pj_scanner *scanner,
/**
* Get characters between quotes. If current input doesn't match begin_quote,
- * syntax error will be thrown.
+ * syntax error will be thrown. Note that the resulting string will contain
+ * the enclosing quote.
*
* @param scanner The scanner.
* @param begin_quote The character to begin the quote.
@@ -333,8 +334,8 @@ PJ_DECL(void) pj_scan_get( pj_scanner *scanner,
* @param out String to store the result.
*/
PJ_DECL(void) pj_scan_get_quote( pj_scanner *scanner,
- int begin_quote, int end_quote,
- pj_str_t *out);
+ int begin_quote, int end_quote,
+ pj_str_t *out);
/**
* Get N characters from the scanner.
@@ -358,15 +359,6 @@ PJ_DECL(int) pj_scan_get_char( pj_scanner *scanner );
/**
- * Get a newline from the scanner. A newline is defined as '\\n', or '\\r', or
- * "\\r\\n". If current input is not newline, syntax error will be thrown.
- *
- * @param scanner The scanner.
- */
-PJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );
-
-
-/**
* Get characters from the scanner and move the scanner position until the
* current character matches the spec.
*
@@ -438,6 +430,34 @@ PJ_DECL(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len);
*/
PJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);
+/**
+ * Perform case insensitive string comparison of string in current position,
+ * knowing that the string to compare only consists of alphanumeric
+ * characters.
+ *
+ * Note that unlike #pj_scan_stricmp, this function can only return zero or
+ * -1.
+ *
+ * @param scanner The scanner.
+ * @param s The string to compare with.
+ * @param len Length of the string to compare with.
+ *
+ * @return zero if equal or -1.
+ *
+ * @see strnicmp_alnum, pj_stricmp_alnum
+ */
+PJ_DECL(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s,
+ int len);
+
+
+/**
+ * Get a newline from the scanner. A newline is defined as '\\n', or '\\r', or
+ * "\\r\\n". If current input is not newline, syntax error will be thrown.
+ *
+ * @param scanner The scanner.
+ */
+PJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );
+
/**
* Manually skip whitespaces according to flag that was specified when
@@ -448,6 +468,13 @@ PJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);
PJ_DECL(void) pj_scan_skip_whitespace( pj_scanner *scanner );
+/**
+ * Skip current line.
+ *
+ * @param scanner The scanner.
+ */
+PJ_DECL(void) pj_scan_skip_line( pj_scanner *scanner );
+
/**
* Save the full scanner state.
*
@@ -469,6 +496,18 @@ PJ_DECL(void) pj_scan_restore_state( pj_scanner *scanner,
pj_scan_state *state);
/**
+ * Get current column position.
+ *
+ * @param scanner The scanner.
+ *
+ * @return The column position.
+ */
+PJ_INLINE(int) pj_scan_get_col( pj_scanner *scanner )
+{
+ return scanner->curptr - scanner->start_line;
+}
+
+/**
* @}
*/
diff --git a/pjlib-util/src/pjlib-util/scanner.c b/pjlib-util/src/pjlib-util/scanner.c
index 77d2db03..f4ef54c6 100644
--- a/pjlib-util/src/pjlib-util/scanner.c
+++ b/pjlib-util/src/pjlib-util/scanner.c
@@ -23,9 +23,10 @@
#include <pj/errno.h>
#include <pj/assert.h>
-#define PJ_SCAN_IS_SPACE(c) ((c)==' ' || (c)=='\t')
-#define PJ_SCAN_IS_NEWLINE(c) ((c)=='\r' || (c)=='\n')
-#define PJ_SCAN_CHECK_EOF(s) (s != end)
+#define PJ_SCAN_IS_SPACE(c) ((c)==' ' || (c)=='\t')
+#define PJ_SCAN_IS_NEWLINE(c) ((c)=='\r' || (c)=='\n')
+#define PJ_SCAN_IS_PROBABLY_SPACE(c) ((c) <= 32)
+#define PJ_SCAN_CHECK_EOF(s) (*s)
#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0
@@ -107,14 +108,12 @@ PJ_DEF(void) pj_scan_init( pj_scanner *scanner, char *bufstart, int buflen,
scanner->begin = scanner->curptr = bufstart;
scanner->end = bufstart + buflen;
scanner->line = 1;
- scanner->col = 1;
+ scanner->start_line = scanner->begin;
scanner->callback = callback;
scanner->skip_ws = options;
if (scanner->skip_ws)
pj_scan_skip_whitespace(scanner);
-
- scanner->col = scanner->curptr - scanner->begin + 1;
}
@@ -128,25 +127,21 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
{
register char *s = scanner->curptr;
- PJ_CHECK_STACK();
-
while (PJ_SCAN_IS_SPACE(*s)) {
++s;
}
- if ((scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE) && PJ_SCAN_IS_NEWLINE(*s)) {
+ if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE)) {
for (;;) {
if (*s == '\r') {
++s;
if (*s == '\n') ++s;
++scanner->line;
- scanner->col = 1;
- scanner->curptr = s;
+ scanner->curptr = scanner->start_line = s;
} else if (*s == '\n') {
++s;
++scanner->line;
- scanner->col = 1;
- scanner->curptr = s;
+ scanner->curptr = scanner->start_line = s;
} else if (PJ_SCAN_IS_SPACE(*s)) {
do {
++s;
@@ -159,7 +154,6 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_WS_HEADER)==PJ_SCAN_AUTOSKIP_WS_HEADER) {
/* Check for header continuation. */
- scanner->col += s - scanner->curptr;
scanner->curptr = s;
if (*s == '\r') {
@@ -168,6 +162,8 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
if (*s == '\n') {
++s;
}
+ scanner->start_line = s;
+
if (PJ_SCAN_IS_SPACE(*s)) {
register char *t = s;
do {
@@ -175,33 +171,43 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
} while (PJ_SCAN_IS_SPACE(*t));
++scanner->line;
- scanner->col = t-s;
scanner->curptr = t;
}
} else {
- scanner->col += s - scanner->curptr;
scanner->curptr = s;
}
}
+PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )
+{
+ char *s = pj_native_strchr(scanner->curptr, '\n');
+ if (!s) {
+ scanner->curptr = scanner->end;
+ } else {
+ scanner->curptr = scanner->start_line = s+1;
+ scanner->line++;
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
+ pj_scan_skip_whitespace(scanner);
+ }
+ }
+}
+
PJ_DEF(int) pj_scan_peek( pj_scanner *scanner,
const pj_cis_t *spec, pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- PJ_CHECK_STACK();
-
- if (pj_scan_is_eof(scanner)) {
+ if (s >= scanner->end) {
pj_scan_syntax_err(scanner);
return -1;
}
- while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s))
+ /* Don't need to check EOF with PJ_SCAN_CHECK_EOF(s) */
+ while (pj_cis_match(spec, *s))
++s;
pj_strset3(out, scanner->curptr, s);
- return s < scanner->end ? *s : 0;
+ return *s;
}
@@ -210,8 +216,6 @@ PJ_DEF(int) pj_scan_peek_n( pj_scanner *scanner,
{
char *endpos = scanner->curptr + len;
- PJ_CHECK_STACK();
-
if (endpos > scanner->end) {
pj_scan_syntax_err(scanner);
return -1;
@@ -227,11 +231,8 @@ PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,
pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- PJ_CHECK_STACK();
-
- if (pj_scan_is_eof(scanner)) {
+ if (s >= scanner->end) {
pj_scan_syntax_err(scanner);
return -1;
}
@@ -240,7 +241,7 @@ PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,
++s;
pj_strset3(out, scanner->curptr, s);
- return s!=scanner->end ? *s : 0;
+ return *s;
}
@@ -248,14 +249,11 @@ PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
const pj_cis_t *spec, pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- char *start = s;
-
- PJ_CHECK_STACK();
pj_assert(pj_cis_match(spec,0)==0);
- if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s)) {
+ /* EOF is detected implicitly */
+ if (!pj_cis_match(spec, *s)) {
pj_scan_syntax_err(scanner);
return;
}
@@ -270,10 +268,9 @@ PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
pj_strset3(out, scanner->curptr, s);
- scanner->col += (s - start);
scanner->curptr = s;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -284,11 +281,7 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- char *start = s;
- PJ_CHECK_STACK();
-
/* Check and eat the begin_quote. */
if (*s != begin_quote) {
pj_scan_syntax_err(scanner);
@@ -300,9 +293,9 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
*/
do {
/* loop until end_quote is found. */
- do {
+ while (*s && *s != '\n' && *s != end_quote) {
++s;
- } while (s != end && *s != '\n' && *s != end_quote);
+ }
/* check that no backslash character precedes the end_quote. */
if (*s == end_quote) {
@@ -318,8 +311,10 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
}
/* break from main loop if we have odd number of backslashes */
if (((unsigned)(q-r) & 0x01) == 1) {
+ ++s;
break;
}
+ ++s;
}
} else {
/* end_quote is not preceeded by backslash. break now. */
@@ -340,34 +335,26 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
pj_strset3(out, scanner->curptr, s);
- scanner->col += (s - start);
scanner->curptr = s;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,
- unsigned N, pj_str_t *out)
+ unsigned N, pj_str_t *out)
{
- register char *s = scanner->curptr;
- char *start = scanner->curptr;
-
- PJ_CHECK_STACK();
-
if (scanner->curptr + N > scanner->end) {
pj_scan_syntax_err(scanner);
return;
}
- pj_strset(out, s, N);
+ pj_strset(out, scanner->curptr, N);
- s += N;
- scanner->col += (s - start);
- scanner->curptr = s;
+ scanner->curptr += N;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -375,20 +362,16 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,
PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
{
- char *start = scanner->curptr;
- int chr = *start;
+ int chr = *scanner->curptr;
- PJ_CHECK_STACK();
-
- if (pj_scan_is_eof(scanner)) {
+ if (!chr) {
pj_scan_syntax_err(scanner);
return 0;
}
++scanner->curptr;
- scanner->col += (scanner->curptr - start);
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
return chr;
@@ -397,8 +380,6 @@ PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
{
- PJ_CHECK_STACK();
-
if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
pj_scan_syntax_err(scanner);
return;
@@ -412,9 +393,9 @@ PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
}
++scanner->line;
- scanner->col = 1;
+ scanner->start_line = scanner->curptr;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -424,12 +405,8 @@ PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
const pj_cis_t *spec, pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- char *start = s;
- PJ_CHECK_STACK();
-
- if (pj_scan_is_eof(scanner)) {
+ if (s >= scanner->end) {
pj_scan_syntax_err(scanner);
return;
}
@@ -440,10 +417,9 @@ PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
pj_strset3(out, scanner->curptr, s);
- scanner->col += (s - start);
scanner->curptr = s;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -453,12 +429,8 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner,
int until_char, pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- char *start = s;
-
- PJ_CHECK_STACK();
- if (pj_scan_is_eof(scanner)) {
+ if (s >= scanner->end) {
pj_scan_syntax_err(scanner);
return;
}
@@ -469,10 +441,9 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner,
pj_strset3(out, scanner->curptr, s);
- scanner->col += (s - start);
scanner->curptr = s;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -482,26 +453,23 @@ PJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner,
const char *until_spec, pj_str_t *out)
{
register char *s = scanner->curptr;
- register char *end = scanner->end;
- char *start = scanner->curptr;
-
- PJ_CHECK_STACK();
+ int speclen;
- if (pj_scan_is_eof(scanner)) {
+ if (s >= scanner->end) {
pj_scan_syntax_err(scanner);
return;
}
- while (PJ_SCAN_CHECK_EOF(s) && !strchr(until_spec, *s)) {
+ speclen = strlen(until_spec);
+ while (PJ_SCAN_CHECK_EOF(s) && !memchr(until_spec, *s, speclen)) {
++s;
}
pj_strset3(out, scanner->curptr, s);
- scanner->col += (s - start);
scanner->curptr = s;
- if (scanner->skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -511,17 +479,14 @@ PJ_DEF(void) pj_scan_advance_n( pj_scanner *scanner,
{
char *start = scanner->curptr;
- PJ_CHECK_STACK();
-
if (scanner->curptr + N > scanner->end) {
pj_scan_syntax_err(scanner);
return;
}
scanner->curptr += N;
- scanner->col += (scanner->curptr - start);
- if (skip_ws) {
+ if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {
pj_scan_skip_whitespace(scanner);
}
}
@@ -546,25 +511,30 @@ PJ_DEF(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len)
return strnicmp(scanner->curptr, s, len);
}
+PJ_DEF(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s,
+ int len)
+{
+ if (scanner->curptr + len > scanner->end) {
+ pj_scan_syntax_err(scanner);
+ return -1;
+ }
+ return strnicmp_alnum(scanner->curptr, s, len);
+}
PJ_DEF(void) pj_scan_save_state( pj_scanner *scanner, pj_scan_state *state)
{
- PJ_CHECK_STACK();
-
state->curptr = scanner->curptr;
state->line = scanner->line;
- state->col = scanner->col;
+ state->start_line = scanner->start_line;
}
PJ_DEF(void) pj_scan_restore_state( pj_scanner *scanner,
pj_scan_state *state)
{
- PJ_CHECK_STACK();
-
scanner->curptr = state->curptr;
scanner->line = state->line;
- scanner->col = state->col;
+ scanner->start_line = state->start_line;
}
diff --git a/pjlib-util/src/pjlib-util/xml.c b/pjlib-util/src/pjlib-util/xml.c
index 35ec96c5..f502df0e 100644
--- a/pjlib-util/src/pjlib-util/xml.c
+++ b/pjlib-util/src/pjlib-util/xml.c
@@ -173,7 +173,7 @@ PJ_DEF(pj_xml_node*) pj_xml_parse( pj_pool_t *pool, char *msg, pj_size_t len)
}
PJ_CATCH_ANY {
PJ_LOG(4,(THIS_FILE, "Syntax error parsing XML in line %d column %d",
- scanner.line, scanner.col));
+ scanner.line, pj_scan_get_col(&scanner)));
}
PJ_END;
pj_scan_fini( &scanner );
diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h
index 83f6ab73..d6fe54ce 100644
--- a/pjlib/include/pj/string.h
+++ b/pjlib/include/pj/string.h
@@ -342,11 +342,29 @@ PJ_IDECL(int) pj_stricmp(const pj_str_t *str1, const pj_str_t *str2);
/**
* Perform lowercase comparison to the strings which consists of only
* alnum characters. More over, it will only return non-zero if both
- * strings are not equal, and is not able to detect which string is
- * 'less'.
+ * strings are not equal, not the usual negative or positive value.
*
* If non-alnum inputs are given, then the function may mistakenly
- * treat two strings as equal while they're not.
+ * treat two strings as equal.
+ *
+ * @param str1 The string to compare.
+ * @param str2 The string to compare.
+ * @param len The length to compare.
+ *
+ * @return
+ * - 0 if str1 is equal to str2
+ * - (-1) if not equal.
+ */
+PJ_IDECL(int) strnicmp_alnum(const char *str1, const char *str2,
+ int len);
+
+/**
+ * Perform lowercase comparison to the strings which consists of only
+ * alnum characters. More over, it will only return non-zero if both
+ * strings are not equal, not the usual negative or positive value.
+ *
+ * If non-alnum inputs are given, then the function may mistakenly
+ * treat two strings as equal.
*
* @param str1 The string to compare.
* @param str2 The string to compare.
diff --git a/pjlib/include/pj/string_i.h b/pjlib/include/pj/string_i.h
index f800ba84..91aebfb0 100644
--- a/pjlib/include/pj/string_i.h
+++ b/pjlib/include/pj/string_i.h
@@ -169,6 +169,39 @@ PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
}
}
+PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,
+ int len)
+{
+ if (len==0)
+ return 0;
+ else {
+ register const pj_uint32_t *p1 = (pj_uint32_t*)str1,
+ *p2 = (pj_uint32_t*)str2;
+ while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
+ ++p1, ++p2, len-=4;
+
+ if (len > 3)
+ return -1;
+#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
+ else if (len==3)
+ return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
+ else if (len==2)
+ return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
+ else if (len==1)
+ return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
+#else
+ else if (len==3)
+ return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
+ else if (len==2)
+ return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
+ else if (len==1)
+ return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
+#endif
+ else
+ return 0;
+ }
+}
+
PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
{
register int len = str1->slen;
@@ -180,25 +213,25 @@ PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
} else {
register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr,
*p2 = (pj_uint32_t*)str2->ptr;
- while (len > 3 && (*p1 & 0x1F1F1F1F)==(*p2 & 0x1F1F1F1F))
+ while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
++p1, ++p2, len-=4;
if (len > 3)
return -1;
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
else if (len==3)
- return ((*p1 & 0x001F1F1F)==(*p2 & 0x001F1F1F)) ? 0 : -1;
+ return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
else if (len==2)
- return ((*p1 & 0x00001F1F)==(*p2 & 0x00001F1F)) ? 0 : -1;
+ return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
else if (len==1)
- return ((*p1 & 0x0000001F)==(*p2 & 0x0000001F)) ? 0 : -1;
+ return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
#else
else if (len==3)
- return ((*p1 & 0x1F1F1F00)==(*p2 & 0x1F1F1F00)) ? 0 : -1;
+ return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
else if (len==2)
- return ((*p1 & 0x1F1F0000)==(*p2 & 0x1F1F0000)) ? 0 : -1;
+ return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
else if (len==1)
- return ((*p1 & 0x1F000000)==(*p2 & 0x1F000000)) ? 0 : -1;
+ return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
#endif
else
return 0;
diff --git a/pjlib/src/pjlib-test/string.c b/pjlib/src/pjlib-test/string.c
index fd94b03c..ba7c9144 100644
--- a/pjlib/src/pjlib-test/string.c
+++ b/pjlib/src/pjlib-test/string.c
@@ -103,6 +103,7 @@ static int stricmp_test(void)
len=1;
STRTEST( 0, "a",buf+0,-510);
STRTEST( 0, "a",buf+1,-512);
+ STRTEST( -1, "0", "P", -514);
/* equal, length=2
* use buffer to simulate non-aligned string.
diff --git a/pjsip/build/pjsip_core.dsp b/pjsip/build/pjsip_core.dsp
index 11de7fd3..92a6353f 100644
--- a/pjsip/build/pjsip_core.dsp
+++ b/pjsip/build/pjsip_core.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
+# ADD CPP /nologo /MD /W4 /Zi /O2 /Oy /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
diff --git a/pjsip/include/pjsip/print_util.h b/pjsip/include/pjsip/print_util.h
index b1362a72..c72d1ab2 100644
--- a/pjsip/include/pjsip/print_util.h
+++ b/pjsip/include/pjsip/print_util.h
@@ -19,53 +19,29 @@
#ifndef __PJSIP_PRINT_H__
#define __PJSIP_PRINT_H__
-/* Minimum space left in the buffer */
-#define MIN_SPACE 10
-
#define copy_advance_check(buf,str) \
do { \
- if ((str).slen+MIN_SPACE >= (endbuf-buf)) return -1; \
+ if ((str).slen >= (endbuf-buf)) return -1; \
pj_memcpy(buf, (str).ptr, (str).slen); \
buf += (str).slen; \
} while (0)
-/*
-static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, int len1, const pj_str_t *str2)
-{
- if (str2->slen) {
- int printed = len1+str2->slen;
- if (printed+MIN_SPACE >= (endbuf-buf)) return NULL;
- pj_memcpy(buf,str1,len1);
- pj_memcpy(buf+len1, str2->ptr, str2->slen);
- return buf + printed;
- } else
- return buf;
-}
-*/
-
#define copy_advance_pair_check(buf,str1,len1,str2) \
do { \
if (str2.slen) { \
printed = len1+str2.slen; \
- if (printed+MIN_SPACE >= (endbuf-buf)) return -1; \
+ if (printed >= (endbuf-buf)) return -1; \
pj_memcpy(buf,str1,len1); \
pj_memcpy(buf+len1, str2.ptr, str2.slen); \
buf += printed; \
} \
} while (0)
-/*
-#define copy_advance_pair(buf,str1,len1,str2) \
- do { \
- buf = imp_copy_advance_pair(buf, endbuf, str1, len1, &str2); \
- if (buf == NULL) return -1; \
- } while (0)
-*/
#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \
do { \
if (str2.slen) { \
printed = len1+str2.slen+2; \
- if (printed+MIN_SPACE >= (endbuf-buf)) return -1; \
+ if (printed >= (endbuf-buf)) return -1; \
pj_memcpy(buf,str1,len1); \
*(buf+len1)=quotebegin; \
pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
@@ -76,16 +52,13 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in
#define copy_advance_pair_escape(buf,str1,len1,str2,unres) \
do { \
- if (str2.slen) { \
- pj_ssize_t esc_len; \
- if (len1+str2.slen+MIN_SPACE >= (endbuf-buf)) return -1; \
- pj_memcpy(buf,str1,len1); \
- buf += len1; \
- esc_len=pj_strncpy2_escape(buf, &str2, (endbuf-buf), &unres); \
- if (esc_len < 0) return -1; \
- buf += esc_len; \
- if (endbuf-buf < MIN_SPACE) return -1; \
- } \
+ if (str2.slen) { \
+ if (len1+str2.slen >= (endbuf-buf)) return -1; \
+ pj_memcpy(buf,str1,len1); \
+ printed=pj_strncpy2_escape(buf,&str2,(endbuf-buf-len1),&unres);\
+ if (printed < 0) return -1; \
+ buf += (printed+len1); \
+ } \
} while (0)
@@ -97,11 +70,10 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in
#define copy_advance_escape(buf,str,unres) \
do { \
- pj_ssize_t len = \
+ printed = \
pj_strncpy2_escape(buf, &(str), (endbuf-buf), &(unres)); \
- if (len < 0) return -1; \
- buf += len; \
- if (endbuf-buf < MIN_SPACE) return -1; \
+ if (printed < 0) return -1; \
+ buf += printed; \
} while (0)
#define copy_advance_pair_no_check(buf,str1,len1,str2) \
@@ -117,10 +89,10 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in
#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
do { \
- if (str2.slen && *str2.ptr!=quotebegin) \
- copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
- else \
- copy_advance_pair(buf,str1,len1,str2); \
+ if (str2.slen && *str2.ptr!=quotebegin) \
+ copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
+ else \
+ copy_advance_pair(buf,str1,len1,str2); \
} while (0)
/*
diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h
index 389e6342..d6e46e5f 100644
--- a/pjsip/include/pjsip/sip_parser.h
+++ b/pjsip/include/pjsip/sip_parser.h
@@ -307,8 +307,10 @@ extern pj_cis_t
pjsip_PROBE_USER_HOST_SPEC, /**< Hostname characters. */
pjsip_PASSWD_SPEC, /**< Password. */
pjsip_USER_SPEC, /**< User */
- pjsip_NEWLINE_OR_EOF_SPEC, /**< For eating up header.*/
- pjsip_DISPLAY_SCAN_SPEC; /**< Used when searching for display name. */
+ pjsip_NOT_NEWLINE, /**< For eating up header, basicly any chars
+ except newlines or zero. */
+ pjsip_NOT_COMMA_OR_NEWLINE, /**< Array elements. */
+ pjsip_DISPLAY_SPEC; /**< Used when searching for display name. */
/*
* Various string constants.
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index 53311f36..79cd68a5 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -104,6 +104,7 @@ struct pjsip_endpoint
static void endpt_transport_callback(pjsip_endpoint*,
pj_status_t, pjsip_rx_data*);
+void init_sip_parser(void);
/*
* This is the global handler for memory allocation failure, for pools that
@@ -373,6 +374,9 @@ PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
endpt->pool = pool;
endpt->pf = pf;
+ /* Init parser. */
+ init_sip_parser();
+
/* Get name. */
if (name != NULL) {
pj_str_t temp;
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
index 49b735b9..6a9828c4 100644
--- a/pjsip/src/pjsip/sip_parser.c
+++ b/pjsip/src/pjsip/sip_parser.c
@@ -65,7 +65,6 @@ static handler_rec handler[127];
static unsigned handler_count;
static int parser_is_initialized;
-
/*
* Global vars (also extern).
*/
@@ -101,9 +100,9 @@ pj_cis_t pjsip_HOST_SPEC, /* For scanning host part. */
pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */
pjsip_PASSWD_SPEC, /* Password. */
pjsip_USER_SPEC, /* User */
- pjsip_ARRAY_ELEMENTS, /* Array separator. */
- pjsip_NEWLINE_OR_EOF_SPEC, /* For eating up header.*/
- pjsip_DISPLAY_SCAN_SPEC; /* Used when searching for display name
+ pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */
+ pjsip_NOT_NEWLINE, /* For eating up header.*/
+ pjsip_DISPLAY_SPEC; /* Used when searching for display name
* in URL. */
@@ -258,14 +257,15 @@ static pj_status_t init_parser()
pj_cis_add_alpha( &pjsip_ALNUM_SPEC );
pj_cis_add_num( &pjsip_ALNUM_SPEC );
- status = pj_cis_init(&cis_buf, &pjsip_NEWLINE_OR_EOF_SPEC);
+ status = pj_cis_init(&cis_buf, &pjsip_NOT_NEWLINE);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str(&pjsip_NEWLINE_OR_EOF_SPEC, "\r\n");
- //pj_cs_set(pjsip_NEWLINE_OR_EOF_SPEC, 0);
+ pj_cis_add_str(&pjsip_NOT_NEWLINE, "\r\n");
+ pj_cis_invert(&pjsip_NOT_NEWLINE);
- status = pj_cis_init(&cis_buf, &pjsip_ARRAY_ELEMENTS);
+ status = pj_cis_init(&cis_buf, &pjsip_NOT_COMMA_OR_NEWLINE);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str( &pjsip_ARRAY_ELEMENTS, ",\r\n");
+ pj_cis_add_str( &pjsip_NOT_COMMA_OR_NEWLINE, ",\r\n");
+ pj_cis_invert(&pjsip_NOT_COMMA_OR_NEWLINE);
status = pj_cis_dup(&pjsip_TOKEN_SPEC, &pjsip_ALNUM_SPEC);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
@@ -300,9 +300,10 @@ static pj_status_t init_parser()
pj_cis_add_str( &pjsip_PROBE_USER_HOST_SPEC, "@ \n>");
pj_cis_invert( &pjsip_PROBE_USER_HOST_SPEC );
- status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SCAN_SPEC);
+ status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SPEC);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str( &pjsip_DISPLAY_SCAN_SPEC, ":\r\n<");
+ pj_cis_add_str( &pjsip_DISPLAY_SPEC, ":\r\n<");
+ pj_cis_invert(&pjsip_DISPLAY_SPEC);
status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
@@ -374,7 +375,7 @@ static pj_status_t init_parser()
return status;
}
-static void init_sip_parser(void)
+void init_sip_parser(void)
{
if (!parser_is_initialized) {
/* Prevent race cond. */
@@ -392,23 +393,27 @@ static void init_sip_parser(void)
* - <0 if handler is 'less' than the header name.
* - >0 if handler is 'greater' than header name.
*/
-static int compare_handler( const handler_rec *r1,
+PJ_INLINE(int) compare_handler( const handler_rec *r1,
const char *name,
pj_size_t name_len,
pj_uint32_t hash )
{
- /* Compare length. */
- if (r1->hname_len < name_len)
- return -1;
- if (r1->hname_len > name_len)
- return 1;
+ PJ_UNUSED_ARG(name_len);
- /* Length is equal, compare hashed value. */
+ /* Compare hashed value. */
if (r1->hname_hash < hash)
return -1;
if (r1->hname_hash > hash)
return 1;
+ /* Compare length. */
+ /*
+ if (r1->hname_len < name_len)
+ return -1;
+ if (r1->hname_len > name_len)
+ return 1;
+ */
+
/* Equal length and equal hash. compare the strings. */
return pj_native_strcmp(r1->hname, name);
}
@@ -609,19 +614,20 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
/* Find the end of header area by finding an empty line. */
- if ((pos = pj_native_strstr(buf, "\n\r\n")) == NULL) {
+ pos = pj_native_strstr(buf, "\n\r\n");
+ if (pos == NULL) {
return PJSIP_EPARTIALMSG;
}
-
+
hdr_end = pos+1;
body_start = pos+3;
/* Find "Content-Length" header the hard way. */
line = pj_native_strchr(buf, '\n');
- while (line && line < hdr_end-14) {
+ while (line && line < hdr_end) {
++line;
if ( ((*line=='C' || *line=='c') &&
- pj_native_strncasecmp(line, "Content-Length", 14) == 0) ||
+ strnicmp_alnum(line, "Content-Length", 14) == 0) ||
((*line=='l' || *line=='L') &&
(*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':')))
{
@@ -744,22 +750,20 @@ static int generic_print_body (pjsip_msg_body *msg_body,
static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
pjsip_parser_err_report *err_list)
{
- int ch;
pjsip_msg *msg;
+ pj_str_t hname;
pjsip_ctype_hdr *ctype_hdr = NULL;
pj_scanner *scanner = ctx->scanner;
pj_pool_t *pool = ctx->pool;
PJ_USE_EXCEPTION;
/* Skip leading newlines. */
- ch = *scanner->curptr;
- while (ch=='\r' || ch=='\n') {
- pj_scan_get_char(scanner);
- ch = *scanner->curptr;
+ while (*scanner->curptr=='\r' || *scanner->curptr=='\n') {
+ pj_scan_get_newline(scanner);
}
/* Parse request or status line */
- if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) == 0) {
+ if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) {
msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG);
int_parse_status_line( scanner, &msg->line.status );
} else {
@@ -768,22 +772,23 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
}
/* Parse headers. */
- do {
- pj_str_t hname;
- pjsip_parse_hdr_func * handler;
- pjsip_hdr *hdr = NULL;
-
- /* Get hname. */
- pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
- ch = pj_scan_get_char( scanner );
- if (ch != ':') {
- PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
- }
+parse_headers:
- /* Find handler. */
- handler = find_handler(&hname);
-
- PJ_TRY {
+ PJ_TRY
+ {
+ do {
+ pjsip_parse_hdr_func * handler;
+ pjsip_hdr *hdr = NULL;
+
+ /* Get hname. */
+ pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
+ if (pj_scan_get_char( scanner ) != ':') {
+ PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
+ }
+
+ /* Find handler. */
+ handler = find_handler(&hname);
+
/* Call the handler if found.
* If no handler is found, then treat the header as generic
* hname/hvalue pair.
@@ -795,46 +800,15 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
hdr->type = PJSIP_H_OTHER;
hdr->name = hdr->sname = hname;
}
-
+
/* Check if we've just parsed a Content-Type header.
- * We will check for a message body if we've got Content-Type header.
+ * We will check for a message body if we've got Content-Type
+ * header.
*/
if (hdr->type == PJSIP_H_CONTENT_TYPE) {
ctype_hdr = (pjsip_ctype_hdr*)hdr;
}
-
- }
- PJ_CATCH_ANY {
- /* Exception was thrown during parsing.
- * Skip until newline, and parse next header.
- */
- pj_str_t token;
- hdr = NULL;
-
- //PJ_LOG(4,("sipparser",
- // "Syntax error in line %d col %d (hname=%.*s)",
- // scanner->line, scanner->col, hname.slen, hname.ptr));
-
- if (err_list) {
- pjsip_parser_err_report *err_info;
- err_info = pj_pool_alloc(pool, sizeof(*err_info));
- err_info->except_code = PJ_GET_EXCEPTION();
- err_info->line = scanner->line;
- err_info->col = scanner->col;
- err_info->hname = hname;
-
- pj_list_insert_before(err_list, err_info);
- }
-
- if (!pj_scan_is_eof(scanner)) {
- pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &token);
- parse_hdr_end(scanner);
- }
- }
- PJ_END;
-
- if (hdr) {
/* Single parse of header line can produce multiple headers.
* For example, if one Contact: header contains Contact list
* separated by comma, then these Contacts will be split into
@@ -842,11 +816,44 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
* So here we must insert list instead of just insert one header.
*/
pj_list_insert_nodes_before(&msg->hdr, hdr);
+
+ /* Parse until EOF or an empty line is found. */
+ } while (!pj_scan_is_eof(scanner) &&
+ *scanner->curptr != '\r' && *scanner->curptr != '\n');
+
+ }
+ PJ_CATCH_ANY
+ {
+ /* Exception was thrown during parsing.
+ * Skip until newline, and parse next header.
+ */
+ pj_str_t token;
+
+ if (err_list) {
+ pjsip_parser_err_report *err_info;
+
+ err_info = pj_pool_alloc(pool, sizeof(*err_info));
+ err_info->except_code = PJ_GET_EXCEPTION();
+ err_info->line = scanner->line;
+ err_info->col = pj_scan_get_col(scanner);
+ err_info->hname = hname;
+
+ pj_list_insert_before(err_list, err_info);
+ }
+
+ if (!pj_scan_is_eof(scanner)) {
+ pj_scan_get(scanner, &pjsip_NOT_NEWLINE, &token);
+ parse_hdr_end(scanner);
+ }
+
+ if (!pj_scan_is_eof(scanner) &&
+ *scanner->curptr != '\r' && *scanner->curptr != '\n');
+ {
+ goto parse_headers;
}
+ }
+ PJ_END;
- /* Parse until EOF or an empty line is found. */
- } while (!pj_scan_is_eof(scanner) &&
- *scanner->curptr != '\r' && *scanner->curptr != '\n');
/* If empty line is found, eat it. */
if (!pj_scan_is_eof(scanner)) {
@@ -858,9 +865,10 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
/* If we have Content-Type header, treat the rest of the message as body.*/
if (ctype_hdr && scanner->curptr!=scanner->end) {
pjsip_msg_body *body = pj_pool_alloc(pool, sizeof(pjsip_msg_body));
- pj_strdup(pool, &body->content_type.type, &ctype_hdr->media.type);
- pj_strdup(pool, &body->content_type.subtype, &ctype_hdr->media.subtype);
- pj_strdup(pool, &body->content_type.param, &ctype_hdr->media.param);
+ body->content_type.type = ctype_hdr->media.type;
+ body->content_type.subtype = ctype_hdr->media.subtype;
+ body->content_type.param = ctype_hdr->media.param;
+
body->data = scanner->curptr;
body->len = scanner->end - scanner->curptr;
body->print_body = &generic_print_body;
@@ -1001,16 +1009,12 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po
uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );
is_name_addr = 1;
} else {
- pj_scan_state backtrack;
pj_str_t scheme;
- int colon;
+ int next_ch;
- pj_scan_save_state( scanner, &backtrack);
- pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &scheme);
- colon = pj_scan_get_char( scanner );
- pj_scan_restore_state( scanner, &backtrack);
+ next_ch = pj_scan_peek( scanner, &pjsip_DISPLAY_SPEC, &scheme);
- if (colon==':' &&
+ if (next_ch==':' &&
(parser_stricmp(scheme, pjsip_SIP_STR)==0 ||
parser_stricmp(scheme, pjsip_SIPS_STR)==0))
{
@@ -1018,7 +1022,7 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po
int_parse_sip_url( scanner, pool,
(opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0);
- } else if (colon==':' && parser_stricmp( scheme, pjsip_TEL_STR)==0) {
+ } else if (next_ch==':') {
/* Not supported. */
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
@@ -1189,7 +1193,7 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner,
* We're only interested in display name, because SIP URL
* will be parser later.
*/
- next = pj_scan_peek_until(scanner, &pjsip_DISPLAY_SCAN_SPEC, &dummy);
+ next = pj_scan_peek(scanner, &pjsip_DISPLAY_SPEC, &dummy);
if (next == '<') {
/* Ok, this is what we're looking for, a display name. */
pj_scan_get_until_ch( scanner, '<', &name_addr->display);
@@ -1205,8 +1209,10 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner,
if (has_bracket)
pj_scan_get_char(scanner);
name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE );
- if (has_bracket)
- pj_scan_get_char(scanner);
+ if (has_bracket) {
+ if (pj_scan_get_char(scanner) != '>')
+ PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);
+ }
return name_addr;
}
@@ -1222,7 +1228,7 @@ static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool,
pjsip_method_init_np( &req_line->method, &token);
req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE);
- if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) != 0)
+ if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0)
PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);
pj_scan_advance_n (scanner, 7, 1);
pj_scan_get_newline( scanner );
@@ -1234,14 +1240,13 @@ static void int_parse_status_line( pj_scanner *scanner,
{
pj_str_t token;
- if (pj_scan_stricmp(scanner, PJSIP_VERSION, 7) != 0)
+ if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0)
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
pj_scan_advance_n( scanner, 7, 1);
pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token);
status_line->code = pj_strtoul(&token);
- pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC,
- &status_line->reason);
+ pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &status_line->reason);
pj_scan_get_newline( scanner );
}
@@ -1267,13 +1272,13 @@ void pjsip_parse_end_hdr_imp( pj_scanner *scanner )
static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
pj_scanner *scanner)
{
- pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, &hdr->values[0]);
+ pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]);
hdr->count++;
while (*scanner->curptr == ',') {
pj_scan_get_char(scanner);
- pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS,
- &hdr->values[hdr->count]);
+ pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE,
+ &hdr->values[hdr->count]);
hdr->count++;
}
parse_hdr_end(scanner);
@@ -1283,7 +1288,11 @@ static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr,
pj_scanner *scanner )
{
- pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue);
+ if (pj_cis_match(&pjsip_NOT_NEWLINE, *scanner->curptr))
+ pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &hdr->hvalue);
+ else
+ hdr->hvalue.slen = 0;
+
parse_hdr_end(scanner);
}
@@ -1292,7 +1301,7 @@ static void parse_generic_int_hdr( pjsip_generic_int_hdr *hdr,
pj_scanner *scanner )
{
pj_str_t tmp;
- pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &tmp);
+ pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &tmp);
hdr->ivalue = pj_strtoul(&tmp);
parse_hdr_end(scanner);
}
@@ -1318,7 +1327,7 @@ static pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx)
static pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx)
{
pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool);
- pj_scan_get_until( ctx->scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id);
+ pj_scan_get( ctx->scanner, &pjsip_NOT_NEWLINE, &hdr->id);
parse_hdr_end(ctx->scanner);
if (ctx->rdata)
@@ -1700,7 +1709,7 @@ static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )
else
pj_list_insert_before(first, hdr);
- if (pj_scan_stricmp( scanner, PJSIP_VERSION "/", 8) != 0)
+ if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0)
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
pj_scan_advance_n( scanner, 8, 1);
diff --git a/pjsip/src/pjsip/sip_uri.c b/pjsip/src/pjsip/sip_uri.c
index a4464254..6c4efb53 100644
--- a/pjsip/src/pjsip/sip_uri.c
+++ b/pjsip/src/pjsip/sip_uri.c
@@ -89,11 +89,19 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,
char *buf, pj_size_t size,
int sep)
{
- const pjsip_param *p = param_list->next;
- char *startbuf = buf;
- char *endbuf = buf + size;
+ const pjsip_param *p;
+ char *startbuf;
+ char *endbuf;
+ int printed;
- while (p != param_list) {
+ p = param_list->next;
+ if (p == param_list)
+ return 0;
+
+ startbuf = buf;
+ endbuf = buf + size;
+
+ do {
*buf++ = (char)sep;
copy_advance_escape(buf, p->name, pjsip_PARAM_CHAR_SPEC);
if (p->value.slen) {
@@ -101,7 +109,8 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,
copy_advance_escape(buf, p->value, pjsip_PARAM_CHAR_SPEC);
}
p = p->next;
- }
+ } while (p != param_list);
+
return buf-startbuf;
}
@@ -248,6 +257,9 @@ static int pjsip_url_print( pjsip_uri_context_e context,
*/
//PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER)
if (url->port && context != PJSIP_URI_IN_FROMTO_HDR) {
+ if (endbuf - buf < 10)
+ return -1;
+
*buf++ = ':';
printed = pj_utoa(url->port, buf);
buf += printed;
@@ -270,8 +282,10 @@ static int pjsip_url_print( pjsip_uri_context_e context,
/* TTL param is not allowed in From, To, Route, and Record-Route header. */
if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&
- context != PJSIP_URI_IN_ROUTING_HDR && (endbuf-buf) > 15)
+ context != PJSIP_URI_IN_ROUTING_HDR)
{
+ if (endbuf - buf < 15)
+ return -1;
pj_memcpy(buf, ";ttl=", 5);
printed = pj_utoa(url->ttl_param, buf+5);
buf += printed + 5;
@@ -288,6 +302,8 @@ static int pjsip_url_print( pjsip_uri_context_e context,
context != PJSIP_URI_IN_CONTACT_HDR)
{
pj_str_t lr = { ";lr", 3 };
+ if (endbuf - buf < 3)
+ return -1;
copy_advance_check(buf, lr);
}
@@ -300,6 +316,8 @@ static int pjsip_url_print( pjsip_uri_context_e context,
/* Header param. */
param = url->header_param.next;
while (param != &url->header_param) {
+ if (endbuf - buf < param->name.slen+2)
+ return -1;
*buf++ = hparam_char;
copy_advance_escape(buf, param->name, pjsip_HDR_CHAR_SPEC);
if (param->value.slen) {
diff --git a/pjsip/src/test-pjsip/msg.c b/pjsip/src/test-pjsip/msg.c
index bfa253bd..1f6affdd 100644
--- a/pjsip/src/test-pjsip/msg.c
+++ b/pjsip/src/test-pjsip/msg.c
@@ -34,7 +34,7 @@ static pjsip_msg *create_msg1(pj_pool_t *pool);
#define FLAG_PARSE_ONLY 4
#define FLAG_PRINT_ONLY 8
-static int flag = FLAG_PARSE_ONLY;
+static int flag = 0;
struct test_msg
{
@@ -105,6 +105,7 @@ static pj_timestamp detect_time, parse_time, print_time;
static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
{
pjsip_msg *parsed_msg, *ref_msg;
+ static pjsip_msg *print_msg;
pj_status_t status = PJ_SUCCESS;
int len;
pj_str_t str1, str2;
@@ -114,15 +115,18 @@ static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
pj_size_t msg_size;
char msgbuf1[PJSIP_MAX_PKT_LEN];
char msgbuf2[PJSIP_MAX_PKT_LEN];
-
enum { BUFLEN = 512 };
entry->len = pj_native_strlen(entry->msg);
if (flag & FLAG_PARSE_ONLY)
goto parse_msg;
- if (flag & FLAG_PRINT_ONLY)
+
+ if (flag & FLAG_PRINT_ONLY) {
+ if (print_msg == NULL)
+ print_msg = entry->creator(pool);
goto print_msg;
+ }
/* Detect message. */
detect_len = detect_len + entry->len;
@@ -144,7 +148,7 @@ static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
pj_sub_timestamp(&t2, &t1);
pj_add_timestamp(&detect_time, &t2);
- if (flag & FLAG_PARSE_ONLY)
+ if (flag & FLAG_DETECT_ONLY)
return PJ_SUCCESS;
/* Parse message. */
@@ -302,7 +306,9 @@ parse_msg:
print_msg:
print_len = print_len + entry->len;
pj_get_timestamp(&t1);
- len = pjsip_msg_print(parsed_msg, msgbuf1, PJSIP_MAX_PKT_LEN);
+ if (flag && FLAG_PRINT_ONLY)
+ ref_msg = print_msg;
+ len = pjsip_msg_print(ref_msg, msgbuf1, PJSIP_MAX_PKT_LEN);
if (len < 1) {
status = -150;
goto on_return;
diff --git a/pjsip/src/test-pjsip/test.c b/pjsip/src/test-pjsip/test.c
index d598dd5d..b940ffa1 100644
--- a/pjsip/src/test-pjsip/test.c
+++ b/pjsip/src/test-pjsip/test.c
@@ -81,8 +81,8 @@ int test_main(void)
PJ_LOG(3,("",""));
- //DO_TEST(uri_test());
- DO_TEST(msg_test());
+ DO_TEST(uri_test());
+ //DO_TEST(msg_test());
on_return: