diff options
Diffstat (limited to 'src/microhttpd/connection.c')
-rw-r--r-- | src/microhttpd/connection.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c index 61023295..8ebc90db 100644 --- a/src/microhttpd/connection.c +++ b/src/microhttpd/connection.c | |||
@@ -1852,10 +1852,11 @@ call_connection_handler (struct MHD_Connection *connection) | |||
1852 | static void | 1852 | static void |
1853 | process_request_body (struct MHD_Connection *connection) | 1853 | process_request_body (struct MHD_Connection *connection) |
1854 | { | 1854 | { |
1855 | size_t processed; | 1855 | uint64_t processed; |
1856 | size_t available; | 1856 | size_t available; |
1857 | size_t used; | 1857 | size_t used; |
1858 | size_t i; | 1858 | size_t i; |
1859 | size_t end_size; | ||
1859 | int instant_retry; | 1860 | int instant_retry; |
1860 | int malformed; | 1861 | int malformed; |
1861 | char *buffer_head; | 1862 | char *buffer_head; |
@@ -1872,7 +1873,7 @@ process_request_body (struct MHD_Connection *connection) | |||
1872 | (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) ) | 1873 | (MHD_SIZE_UNKNOWN == connection->remaining_upload_size) ) |
1873 | { | 1874 | { |
1874 | if ( (connection->current_chunk_offset == connection->current_chunk_size) && | 1875 | if ( (connection->current_chunk_offset == connection->current_chunk_size) && |
1875 | (0 != connection->current_chunk_offset) && | 1876 | (0LLU != connection->current_chunk_offset) && |
1876 | (available >= 2) ) | 1877 | (available >= 2) ) |
1877 | { | 1878 | { |
1878 | /* skip new line at the *end* of a chunk */ | 1879 | /* skip new line at the *end* of a chunk */ |
@@ -1915,28 +1916,41 @@ process_request_body (struct MHD_Connection *connection) | |||
1915 | while (i < available) | 1916 | while (i < available) |
1916 | { | 1917 | { |
1917 | if ( ('\r' == buffer_head[i]) || | 1918 | if ( ('\r' == buffer_head[i]) || |
1918 | ('\n' == buffer_head[i]) ) | 1919 | ('\n' == buffer_head[i]) || |
1920 | (';' == buffer_head[i]) ) | ||
1919 | break; | 1921 | break; |
1920 | i++; | 1922 | i++; |
1921 | if (i >= 6) | 1923 | if (i >= 16) |
1922 | break; | 1924 | break; |
1923 | } | 1925 | } |
1924 | /* take '\n' into account; if '\n' | 1926 | end_size = i; |
1925 | is the unavailable character, we | 1927 | /* find beginning of CRLF (skip over chunk extensions) */ |
1926 | will need to wait until we have it | 1928 | if (';' == buffer_head[i]) |
1929 | { | ||
1930 | while (i < available) | ||
1931 | { | ||
1932 | if ( ('\r' == buffer_head[i]) || | ||
1933 | ('\n' == buffer_head[i]) ) | ||
1934 | break; | ||
1935 | i++; | ||
1936 | } | ||
1937 | } | ||
1938 | /* take '\n' into account; if '\n' is the unavailable | ||
1939 | character, we will need to wait until we have it | ||
1927 | before going further */ | 1940 | before going further */ |
1928 | if ( (i + 1 >= available) && | 1941 | if ( (i + 1 >= available) && |
1929 | ! ( (1 == i) && | 1942 | ! ( (1 == i) && |
1930 | (2 == available) && | 1943 | (2 == available) && |
1931 | ('0' == buffer_head[0]) ) ) | 1944 | ('0' == buffer_head[0]) ) ) |
1932 | break; /* need more data... */ | 1945 | break; /* need more data... */ |
1933 | malformed = (i >= 6); | 1946 | i++; |
1947 | malformed = (end_size >= 16); | ||
1934 | if (! malformed) | 1948 | if (! malformed) |
1935 | { | 1949 | { |
1936 | size_t num_dig = MHD_strx_to_sizet_n_ (buffer_head, | 1950 | size_t num_dig = MHD_strx_to_uint64_n_ (buffer_head, |
1937 | i, | 1951 | end_size, |
1938 | &connection->current_chunk_size); | 1952 | &connection->current_chunk_size); |
1939 | malformed = (i != num_dig); | 1953 | malformed = (end_size != num_dig); |
1940 | } | 1954 | } |
1941 | if (malformed) | 1955 | if (malformed) |
1942 | { | 1956 | { |
@@ -1945,11 +1959,11 @@ process_request_body (struct MHD_Connection *connection) | |||
1945 | _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n")); | 1959 | _("Received malformed HTTP request (bad chunked encoding). Closing connection.\n")); |
1946 | return; | 1960 | return; |
1947 | } | 1961 | } |
1948 | i++; | 1962 | /* skip 2nd part of line feed */ |
1949 | if ( (i < available) && | 1963 | if ( (i < available) && |
1950 | ( ('\r' == buffer_head[i]) || | 1964 | ( ('\r' == buffer_head[i]) || |
1951 | ('\n' == buffer_head[i]) ) ) | 1965 | ('\n' == buffer_head[i]) ) ) |
1952 | i++; /* skip 2nd part of line feed */ | 1966 | i++; |
1953 | 1967 | ||
1954 | buffer_head += i; | 1968 | buffer_head += i; |
1955 | available -= i; | 1969 | available -= i; |
@@ -1957,7 +1971,7 @@ process_request_body (struct MHD_Connection *connection) | |||
1957 | 1971 | ||
1958 | if (available > 0) | 1972 | if (available > 0) |
1959 | instant_retry = MHD_YES; | 1973 | instant_retry = MHD_YES; |
1960 | if (0 == connection->current_chunk_size) | 1974 | if (0LLU == connection->current_chunk_size) |
1961 | { | 1975 | { |
1962 | connection->remaining_upload_size = 0; | 1976 | connection->remaining_upload_size = 0; |
1963 | break; | 1977 | break; |