mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
For#1508, check the error correctly for strtol.
This commit is contained in:
parent
cab15c348c
commit
da7e76c96a
3 changed files with 211 additions and 8 deletions
|
@ -992,15 +992,14 @@ srs_error_t SrsHttpResponseReader::read_chunked(char* data, int nb_data, int* nb
|
||||||
at[length - 1] = 0;
|
at[length - 1] = 0;
|
||||||
at[length - 2] = 0;
|
at[length - 2] = 0;
|
||||||
|
|
||||||
// The at is length in string, it must be all digital.
|
|
||||||
if (!srs_is_digit_number(at)) {
|
|
||||||
return srs_error_new(ERROR_HTTP_INVALID_CHUNK_HEADER, "invalid length=%s", at);
|
|
||||||
}
|
|
||||||
|
|
||||||
// size is the bytes size, excludes the chunk header and end CRLF.
|
// size is the bytes size, excludes the chunk header and end CRLF.
|
||||||
int ilength = (int)::strtol(at, NULL, 16);
|
// @remark It must be hex format, please read https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#Directives
|
||||||
if (ilength < 0) {
|
// @remark For strtol, note that: If no conversion could be performed, 0 is returned and the global variable errno is set to EINVAL.
|
||||||
return srs_error_new(ERROR_HTTP_INVALID_CHUNK_HEADER, "invalid length=%s as %d", at, ilength);
|
char* at_parsed = at; errno = 0;
|
||||||
|
int ilength = (int)::strtol(at, &at_parsed, 16);
|
||||||
|
if (ilength < 0 || errno != 0 || at_parsed - at != length - 2) {
|
||||||
|
return srs_error_new(ERROR_HTTP_INVALID_CHUNK_HEADER, "invalid length %s as %d, parsed=%.*s, errno=%d",
|
||||||
|
at, ilength, (int)(at_parsed-at), at, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
// all bytes in chunk is left now.
|
// all bytes in chunk is left now.
|
||||||
|
|
|
@ -251,6 +251,26 @@ VOID TEST(ProtocolHTTPTest, ResponseWriter)
|
||||||
|
|
||||||
__MOCK_HTTP_EXPECT_STREQ2(200, "5\r\nHello\r\n8\r\n, world!\r\n0\r\n\r\n", w);
|
__MOCK_HTTP_EXPECT_STREQ2(200, "5\r\nHello\r\n8\r\n, world!\r\n0\r\n\r\n", w);
|
||||||
}
|
}
|
||||||
|
if (true) {
|
||||||
|
MockResponseWriter w;
|
||||||
|
|
||||||
|
w.header()->set_content_type("application/octet-stream");
|
||||||
|
w.write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
w.write((char*)"Hello, world!", 13);
|
||||||
|
w.final_request();
|
||||||
|
|
||||||
|
__MOCK_HTTP_EXPECT_STREQ2(200, "d\r\nHello, world!\r\n0\r\n\r\n", w);
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
MockResponseWriter w;
|
||||||
|
|
||||||
|
w.header()->set_content_type("application/octet-stream");
|
||||||
|
w.write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
w.write((char*)"Hello, world!", 13);
|
||||||
|
w.final_request();
|
||||||
|
|
||||||
|
__MOCK_HTTP_EXPECT_STREQ2(200, "d\r\nHello, world!\r\n0\r\n\r\n", w);
|
||||||
|
}
|
||||||
|
|
||||||
// If directly write empty string, sent an empty response with content-length 0
|
// If directly write empty string, sent an empty response with content-length 0
|
||||||
if (true) {
|
if (true) {
|
||||||
|
@ -267,6 +287,42 @@ VOID TEST(ProtocolHTTPTest, ResponseWriter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID TEST(ProtocolHTTPTest, ClientRequest)
|
||||||
|
{
|
||||||
|
srs_error_t err;
|
||||||
|
|
||||||
|
// Normal case, with chunked encoding.
|
||||||
|
if (true) {
|
||||||
|
MockBufferIO io; io.append(mock_http_response2(200, "0d\r\nHello, world!\r\n0\r\n\r\n"));
|
||||||
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE, false));
|
||||||
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
||||||
|
string res; HELPER_ASSERT_SUCCESS(msg->body_read_all(res));
|
||||||
|
EXPECT_EQ(200, msg->status_code());
|
||||||
|
EXPECT_STREQ("Hello, world!", res.c_str());
|
||||||
|
srs_freep(msg);
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
MockBufferIO io; io.append(mock_http_response2(200, "6\r\nHello!\r\n0\r\n\r\n"));
|
||||||
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE, false));
|
||||||
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
||||||
|
string res; HELPER_ASSERT_SUCCESS(msg->body_read_all(res));
|
||||||
|
EXPECT_EQ(200, msg->status_code());
|
||||||
|
EXPECT_STREQ("Hello!", res.c_str());
|
||||||
|
srs_freep(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal case, with specified content-length.
|
||||||
|
if (true) {
|
||||||
|
MockBufferIO io; io.append(mock_http_response(200, "Hello, world!"));
|
||||||
|
SrsHttpParser hp; HELPER_ASSERT_SUCCESS(hp.initialize(HTTP_RESPONSE, false));
|
||||||
|
ISrsHttpMessage* msg = NULL; HELPER_ASSERT_SUCCESS(hp.parse_message(&io, &msg));
|
||||||
|
string res; HELPER_ASSERT_SUCCESS(msg->body_read_all(res));
|
||||||
|
EXPECT_EQ(200, msg->status_code());
|
||||||
|
EXPECT_STREQ("Hello, world!", res.c_str());
|
||||||
|
srs_freep(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID TEST(ProtocolHTTPTest, ResponseHTTPError)
|
VOID TEST(ProtocolHTTPTest, ResponseHTTPError)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
srs_error_t err;
|
||||||
|
|
|
@ -27,6 +27,7 @@ using namespace std;
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
#include <srs_app_listener.hpp>
|
#include <srs_app_listener.hpp>
|
||||||
#include <srs_service_st.hpp>
|
#include <srs_service_st.hpp>
|
||||||
|
#include <srs_service_utility.hpp>
|
||||||
|
|
||||||
// Disable coroutine test for OSX.
|
// Disable coroutine test for OSX.
|
||||||
#if !defined(SRS_OSX)
|
#if !defined(SRS_OSX)
|
||||||
|
@ -225,6 +226,153 @@ VOID TEST(TCPServerTest, PingPongWithTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID TEST(TCPServerTest, StringIsDigital)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(0, ::atoi("0"));
|
||||||
|
EXPECT_EQ(0, ::atoi("0000000000"));
|
||||||
|
EXPECT_EQ(1, ::atoi("01"));
|
||||||
|
EXPECT_EQ(12, ::atoi("012"));
|
||||||
|
EXPECT_EQ(1234567890L, ::atol("1234567890"));
|
||||||
|
EXPECT_EQ(123456789L, ::atol("0123456789"));
|
||||||
|
EXPECT_EQ(1234567890, ::atoi("1234567890a"));
|
||||||
|
EXPECT_EQ(10, ::atoi("10e3"));
|
||||||
|
EXPECT_EQ(0, ::atoi("!1234567890"));
|
||||||
|
EXPECT_EQ(0, ::atoi(""));
|
||||||
|
|
||||||
|
EXPECT_TRUE(srs_is_digit_number("0"));
|
||||||
|
EXPECT_TRUE(srs_is_digit_number("0000000000"));
|
||||||
|
EXPECT_TRUE(srs_is_digit_number("1234567890"));
|
||||||
|
EXPECT_TRUE(srs_is_digit_number("0123456789"));
|
||||||
|
EXPECT_FALSE(srs_is_digit_number("1234567890a"));
|
||||||
|
EXPECT_FALSE(srs_is_digit_number("a1234567890"));
|
||||||
|
EXPECT_FALSE(srs_is_digit_number("10e3"));
|
||||||
|
EXPECT_FALSE(srs_is_digit_number("!1234567890"));
|
||||||
|
EXPECT_FALSE(srs_is_digit_number(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID TEST(TCPServerTest, StringIsHex)
|
||||||
|
{
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"0";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 1, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"0";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 1, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"0000000000";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 10, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"01";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x1, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 2, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"012";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x12, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 3, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"1234567890";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x1234567890L, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 10, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"0123456789";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x123456789L, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 10, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"1234567890a";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x1234567890a, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 11, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"0x1234567890a";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x1234567890a, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 13, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"1234567890f";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x1234567890f, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 11, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"10e3";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x10e3, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 4, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"!1234567890";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"1234567890g";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x1234567890, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str + 10, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x0, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_EQ(0, errno);
|
||||||
|
EXPECT_EQ(str, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
char* str = (char*)"1fffffffffffffffffffffffffffff";
|
||||||
|
char* parsed = str; errno = 0;
|
||||||
|
EXPECT_EQ(0x7fffffffffffffff, ::strtol(str, &parsed, 16));
|
||||||
|
EXPECT_NE(0, errno);
|
||||||
|
EXPECT_EQ(str+30, parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID TEST(TCPServerTest, WritevIOVC)
|
VOID TEST(TCPServerTest, WritevIOVC)
|
||||||
{
|
{
|
||||||
srs_error_t err;
|
srs_error_t err;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue