This is an automated email from the ASF dual-hosted git repository. billblough pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git
The following commit(s) were added to refs/heads/master by this push: new 7de8363 Fix 1-byte buffer overwrites due to null-termination 7de8363 is described below commit 7de836303e80dcd2cdeb675be3bf66c2290776d2 Author: Bill Blough <billblo...@apache.org> AuthorDate: Thu Sep 3 22:14:01 2020 -0400 Fix 1-byte buffer overwrites due to null-termination Add axutil_stream_set_buffer_end_null function to allow memory reallocation if needed when null-terminating a basic stream. Fixes: AXIS2C-1600 --- axiom/src/om/om_data_source.c | 4 +--- .../transport/http/common/simple_http_svr_conn.c | 2 +- test/core/transport/http/test_http_transport.cc | 21 +++++++++++++++++ util/include/axutil_stream.h | 10 ++++++++ util/src/stream.c | 27 ++++++++++++++++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/axiom/src/om/om_data_source.c b/axiom/src/om/om_data_source.c index 3959e49..4f6db77 100644 --- a/axiom/src/om/om_data_source.c +++ b/axiom/src/om/om_data_source.c @@ -108,16 +108,14 @@ axiom_data_source_serialize( { int status = AXIS2_SUCCESS; axis2_char_t *data = NULL; - unsigned int data_len = 0; AXIS2_ENV_CHECK(env, AXIS2_FAILURE); AXIS2_PARAM_CHECK(env->error, om_output, AXIS2_FAILURE); + axutil_stream_set_buffer_end_null(data_source->stream, env); data = axutil_stream_get_buffer(data_source->stream, env); - data_len = axutil_stream_get_len(data_source->stream, env); if(data) { - data[data_len] = '\0'; status = axiom_output_write(om_output, env, AXIOM_DATA_SOURCE, 1, data); } return status; diff --git a/src/core/transport/http/common/simple_http_svr_conn.c b/src/core/transport/http/common/simple_http_svr_conn.c index 958be28..4aa71e6 100644 --- a/src/core/transport/http/common/simple_http_svr_conn.c +++ b/src/core/transport/http/common/simple_http_svr_conn.c @@ -282,9 +282,9 @@ axis2_simple_http_svr_conn_write_response( if(response_stream) { body_size = axutil_stream_get_len(response_stream, env); + axutil_stream_set_buffer_end_null(response_stream, env); response_body = axutil_stream_get_buffer(response_stream, env); axutil_stream_flush_buffer(response_stream, env); - response_body[body_size] = AXIS2_ESC_NULL; } if(body_size <= 0 && !binary_content) diff --git a/test/core/transport/http/test_http_transport.cc b/test/core/transport/http/test_http_transport.cc index 86d1b2f..17ee4a0 100644 --- a/test/core/transport/http/test_http_transport.cc +++ b/test/core/transport/http/test_http_transport.cc @@ -32,6 +32,7 @@ #include <axis2_json_writer.h> #include <axis2_json_reader.h> #endif +#include <axis2_simple_http_svr_conn.h> #include "../../../cutest/include/cut_http_server.h" @@ -450,3 +451,23 @@ TEST_F(TestHTTPTransport, test_json) } #endif + +TEST_F(TestHTTPTransport, test_AXIS2C_1600) +{ + axis2_simple_http_svr_conn_t* conn = axis2_simple_http_svr_conn_create( + m_env, -1); + + axis2_http_simple_response_t* resp = axis2_http_simple_response_create( + m_env, NULL, NULL, 0, NULL); + axis2_char_t body[AXIS2_STREAM_DEFAULT_BUF_SIZE+1]; + memset(body, 'A', AXIS2_STREAM_DEFAULT_BUF_SIZE+1); + body[AXIS2_STREAM_DEFAULT_BUF_SIZE] = '\0'; + + axis2_http_simple_response_set_status_line(resp, m_env, "1.1", 200, "OK"); + axis2_http_simple_response_set_body_string(resp, m_env, body); + + axis2_simple_http_svr_conn_write_response(conn, m_env, resp); + + axis2_http_simple_response_free(resp, m_env); + axis2_simple_http_svr_conn_free(conn, m_env); +} diff --git a/util/include/axutil_stream.h b/util/include/axutil_stream.h index a506811..92c9c17 100644 --- a/util/include/axutil_stream.h +++ b/util/include/axutil_stream.h @@ -283,6 +283,16 @@ extern "C" const axutil_stream_t * stream, const axutil_env_t * env); + /** + * Appends a null terminator to the buffer, allocating additional memory + * if necessary. + * @return Length of the buffer plus null terminator, or -1 on error + */ + AXIS2_EXTERN int AXIS2_CALL + axutil_stream_set_buffer_end_null( + axutil_stream_t *stream, + axutil_env_t *env); + AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_stream_flush_buffer( axutil_stream_t * stream, diff --git a/util/src/stream.c b/util/src/stream.c index bdc4e03..8f3d986 100644 --- a/util/src/stream.c +++ b/util/src/stream.c @@ -377,6 +377,33 @@ axutil_stream_get_buffer( return stream->buffer; } +AXIS2_EXTERN int AXIS2_CALL +axutil_stream_set_buffer_end_null( + axutil_stream_t *stream, + axutil_env_t *env) +{ + if (!stream || !env) return -1; + + if (stream->len + 1 >= stream->max_len) { + + axis2_char_t *tmp = (axis2_char_t *)AXIS2_MALLOC(env->allocator, + sizeof(axis2_char_t) * (stream->len + 1)); + if(!tmp) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + return -1; + } + stream->max_len = stream->len + 1; + memcpy(tmp, stream->buffer_head, sizeof(axis2_char_t) * stream->len); + AXIS2_FREE(env->allocator, stream->buffer_head); + stream->buffer = tmp; + stream->buffer_head = tmp; + } + *(stream->buffer_head + stream->len) = '\0'; + return stream->len + 1; + +} + AXIS2_EXTERN axis2_status_t AXIS2_CALL axutil_stream_flush_buffer( axutil_stream_t *stream,