For#1508, check the error correctly for strtol.

pull/1568/head
winlin 5 years ago
parent cab15c348c
commit da7e76c96a

@ -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…
Cancel
Save