From: Walter Doekes Date: Wed, 23 Nov 2011 20:45:35 +0000 (+0000) Subject: Minor cleanup in chan_sip get_msg_text() function. X-Git-Tag: 10.1.0-rc1~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9aafe858d7a46603c0e2fdf5aa6b93c9a7c8c509;p=thirdparty%2Fasterisk.git Minor cleanup in chan_sip get_msg_text() function. In r116240, get_msg_text() got an extra parameter to fix the unwanted addition of trailing newlines to SIP MESSAGE bodies. This caused all linefeeds to be trimmed, which isn't right either. This is a stop-gap; the right fix is to return the original SIP request body. Review: https://reviewboard.asterisk.org/r/1586 Reviewed by: Matt Jordan ........ Merged revisions 346147 from http://svn.asterisk.org/svn/asterisk/branches/1.8 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@346198 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index c1ff3092f6..8ab68ec3de 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1489,7 +1489,7 @@ static void check_via(struct sip_pvt *p, struct sip_request *req); static int get_rpid(struct sip_pvt *p, struct sip_request *oreq); static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason); static enum sip_get_dest_result get_destination(struct sip_pvt *p, struct sip_request *oreq, int *cc_recall_core_id); -static int get_msg_text(char *buf, int len, struct sip_request *req, int addnewline); +static int get_msg_text(char *buf, int len, struct sip_request *req); static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout); static void update_connectedline(struct sip_pvt *p, const void *data, size_t datalen); static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen); @@ -16324,30 +16324,37 @@ static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, return check_user_full(p, req, sipmethod, uri, reliable, addr, NULL); } -/*! \brief Get text out of a SIP MESSAGE packet */ -static int get_msg_text(char *buf, int len, struct sip_request *req, int addnewline) +/*! \brief Get message body from a SIP request + * \param buf Destination buffer + * \param len Destination buffer size + * \param req The SIP request + * + * When parsing the request originally, the lines are split by LF or CRLF. + * This function adds a single LF after every line. + */ +static int get_msg_text(char *buf, int len, struct sip_request *req) { int x; - int y; + int linelen; buf[0] = '\0'; - /*XXX isn't strlen(buf) going to always be 0? */ - y = len - strlen(buf) - 5; - if (y < 0) - y = 0; - for (x = 0; x < req->lines; x++) { + --len; /* reserve strncat null */ + for (x = 0; len && x < req->lines; ++x) { const char *line = REQ_OFFSET_TO_STR(req, line[x]); - strncat(buf, line, y); /* safe */ - y -= strlen(line) + 1; - if (y < 0) - y = 0; - if (y != 0 && addnewline) + strncat(buf, line, len); /* safe */ + linelen = strlen(buf); + buf += linelen; + len -= linelen; + if (len) { strcat(buf, "\n"); /* safe */ + ++buf; + --len; + } } return 0; } -static int get_msg_text2(struct ast_str **buf, struct sip_request *req, int addnewline) +static int get_msg_text2(struct ast_str **buf, struct sip_request *req) { int i, res = 0; @@ -16356,7 +16363,7 @@ static int get_msg_text2(struct ast_str **buf, struct sip_request *req, int addn for (i = 0; res >= 0 && i < req->lines; i++) { const char *line = REQ_OFFSET_TO_STR(req, line[i]); - res = ast_str_append(buf, 0, "%s%s", line, addnewline ? "\n" : ""); + res = ast_str_append(buf, 0, "%s\n", line); } return res < 0 ? -1 : 0; @@ -16388,6 +16395,8 @@ AST_THREADSTORAGE(sip_msg_buf); static void receive_message(struct sip_pvt *p, struct sip_request *req, struct ast_sockaddr *addr, const char *e) { struct ast_str *buf; + char *cbuf; + size_t len; struct ast_frame f; const char *content_type = sip_get_header(req, "Content-Type"); struct ast_msg *msg; @@ -16409,11 +16418,7 @@ static void receive_message(struct sip_pvt *p, struct sip_request *req, struct a return; } - /* If this is an out of dialog msg, add back newlines, otherwise strip the new lines. - * In dialog msg's newlines are stripped to preserve the behavior of how Asterisk has worked - * in the past. If it is found later that new lines can be added into in dialog msgs as well, - * then change this. */ - if (get_msg_text2(&buf, req, p->owner ? FALSE : TRUE)) { + if (get_msg_text2(&buf, req)) { ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid); transmit_response(p, "202 Accepted", req); if (!p->owner) @@ -16421,6 +16426,18 @@ static void receive_message(struct sip_pvt *p, struct sip_request *req, struct a return; } + /* Strip trailing line feeds from message body. (get_msg_text2 may add + * a trailing linefeed and we don't need any at the end) */ + cbuf = ast_str_buffer(buf); + len = ast_str_strlen(buf); + while (len > 0) { + if (cbuf[--len] != '\n') { + ++len; + break; + } + } + ast_str_truncate(buf, len); + if (p->owner) { if (sip_debug_test_pvt(p)) ast_verbose("SIP Text message received: '%s'\n", ast_str_buffer(buf)); @@ -19042,7 +19059,7 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req) return; } - get_msg_text(buf, sizeof(buf), req, TRUE); + get_msg_text(buf, sizeof(buf), req); duration = 100; /* 100 ms */ if (ast_strlen_zero(buf)) { @@ -22059,7 +22076,7 @@ static int handle_request_notify(struct sip_pvt *p, struct sip_request *req, str } /* Get the text of the attachment */ - if (get_msg_text(buf, sizeof(buf), req, TRUE)) { + if (get_msg_text(buf, sizeof(buf), req)) { ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid); transmit_response(p, "400 Bad request", req); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);