Skip to content

Commit e039428

Browse files
committed
Experimental: bump 30 bit receive limit to 62 bit
1 parent 77a6f42 commit e039428

3 files changed

Lines changed: 27 additions & 27 deletions

File tree

src/ChunkedEncoding.h

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@
2929

3030
namespace uWS {
3131

32-
constexpr uint32_t STATE_HAS_SIZE = 0x80000000;
33-
constexpr uint32_t STATE_IS_CHUNKED = 0x40000000;
34-
constexpr uint32_t STATE_SIZE_MASK = 0x3FFFFFFF;
35-
constexpr uint32_t STATE_IS_ERROR = 0xFFFFFFFF;
36-
constexpr uint32_t STATE_SIZE_OVERFLOW = 0x0F000000;
32+
constexpr uint64_t STATE_HAS_SIZE = 1ull << (sizeof(uint64_t) * 8 - 1);//0x80000000;
33+
constexpr uint64_t STATE_IS_CHUNKED = 1ull << (sizeof(uint64_t) * 8 - 2);//0x40000000;
34+
constexpr uint64_t STATE_SIZE_MASK = ~(3ull << (sizeof(uint64_t) * 8 - 2));//0x3FFFFFFF;
35+
constexpr uint64_t STATE_IS_ERROR = ~0ull;//0xFFFFFFFF;
36+
constexpr uint64_t STATE_SIZE_OVERFLOW = 0x0Full << (sizeof(uint64_t) * 8 - 8);//0x0F000000;
3737

38-
inline unsigned int chunkSize(unsigned int state) {
38+
inline uint64_t chunkSize(uint64_t state) {
3939
return state & STATE_SIZE_MASK;
4040
}
4141

4242
/* Reads hex number until CR or out of data to consume. Updates state. Returns bytes consumed. */
43-
inline void consumeHexNumber(std::string_view &data, unsigned int &state) {
43+
inline void consumeHexNumber(std::string_view &data, uint64_t &state) {
4444
/* Consume everything higher than 32 */
4545
while (data.length() && data.data()[0] > 32) {
4646

@@ -59,9 +59,9 @@ namespace uWS {
5959
}
6060

6161
// extract state bits
62-
unsigned int bits = /*state &*/ STATE_IS_CHUNKED;
62+
uint64_t bits = /*state &*/ STATE_IS_CHUNKED;
6363

64-
state = (state & STATE_SIZE_MASK) * 16u + number;
64+
state = (state & STATE_SIZE_MASK) * 16ull + number;
6565

6666
state |= bits;
6767
data.remove_prefix(1);
@@ -78,7 +78,7 @@ namespace uWS {
7878
}
7979
}
8080

81-
inline void decChunkSize(unsigned int &state, unsigned int by) {
81+
inline void decChunkSize(uint64_t &state, unsigned int by) {
8282

8383
//unsigned int bits = state & STATE_IS_CHUNKED;
8484

@@ -87,21 +87,21 @@ namespace uWS {
8787
//state |= bits;
8888
}
8989

90-
inline bool hasChunkSize(unsigned int state) {
90+
inline bool hasChunkSize(uint64_t state) {
9191
return state & STATE_HAS_SIZE;
9292
}
9393

9494
/* Are we in the middle of parsing chunked encoding? */
95-
inline bool isParsingChunkedEncoding(unsigned int state) {
95+
inline bool isParsingChunkedEncoding(uint64_t state) {
9696
return state & ~STATE_SIZE_MASK;
9797
}
9898

99-
inline bool isParsingInvalidChunkedEncoding(unsigned int state) {
99+
inline bool isParsingInvalidChunkedEncoding(uint64_t state) {
100100
return state == STATE_IS_ERROR;
101101
}
102102

103103
/* Returns next chunk (empty or not), or if all data was consumed, nullopt is returned. */
104-
static std::optional<std::string_view> getNextChunk(std::string_view &data, unsigned int &state, bool trailer = false) {
104+
static std::optional<std::string_view> getNextChunk(std::string_view &data, uint64_t &state, bool trailer = false) {
105105

106106
while (data.length()) {
107107

@@ -167,7 +167,7 @@ namespace uWS {
167167
/* We will consume all our input data */
168168
std::string_view emitSoon;
169169
if (chunkSize(state) > 2) {
170-
unsigned int maximalAppEmit = chunkSize(state) - 2;
170+
uint64_t maximalAppEmit = chunkSize(state) - 2;
171171
if (data.length() > maximalAppEmit) {
172172
emitSoon = data.substr(0, maximalAppEmit);
173173
} else {
@@ -195,10 +195,10 @@ namespace uWS {
195195

196196
std::string_view *data;
197197
std::optional<std::string_view> chunk;
198-
unsigned int *state;
198+
uint64_t *state;
199199
bool trailer;
200200

201-
ChunkIterator(std::string_view *data, unsigned int *state, bool trailer = false) : data(data), state(state), trailer(trailer) {
201+
ChunkIterator(std::string_view *data, uint64_t *state, bool trailer = false) : data(data), state(state), trailer(trailer) {
202202
chunk = uWS::getNextChunk(*data, *state, trailer);
203203
}
204204

src/HttpParser.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ struct HttpParser {
180180
private:
181181
std::string fallback;
182182
/* This guy really has only 30 bits since we reserve two highest bits to chunked encoding parsing state */
183-
unsigned int remainingStreamingBytes = 0;
183+
uint64_t remainingStreamingBytes = 0;
184184

185185
/* Returns UINT_MAX on error. Maximum 999999999 is allowed. */
186186
static unsigned int toUnsignedInteger(std::string_view str) {
@@ -506,7 +506,7 @@ struct HttpParser {
506506
}
507507

508508
if (!CONSUME_MINIMALLY) {
509-
unsigned int emittable = std::min<unsigned int>(remainingStreamingBytes, length);
509+
unsigned int emittable = (unsigned int) std::min<uint64_t>(remainingStreamingBytes, length);
510510
dataHandler(user, std::string_view(data, emittable), emittable == remainingStreamingBytes);
511511
remainingStreamingBytes -= emittable;
512512

@@ -561,8 +561,8 @@ struct HttpParser {
561561
} else {
562562
void *returnedUser = dataHandler(user, std::string_view(data, remainingStreamingBytes), true);
563563

564-
data += remainingStreamingBytes;
565-
length -= remainingStreamingBytes;
564+
data += (unsigned int) remainingStreamingBytes;
565+
length -= (unsigned int) remainingStreamingBytes;
566566

567567
remainingStreamingBytes = 0;
568568

@@ -617,8 +617,8 @@ struct HttpParser {
617617
} else {
618618
void *returnedUser = dataHandler(user, std::string_view(data, remainingStreamingBytes), true);
619619

620-
data += remainingStreamingBytes;
621-
length -= remainingStreamingBytes;
620+
data += (unsigned int) remainingStreamingBytes;
621+
length -= (unsigned int) remainingStreamingBytes;
622622

623623
remainingStreamingBytes = 0;
624624

tests/ChunkedEncoding.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "../src/ChunkedEncoding.h"
99

10-
void consumeChunkEncoding(int maxConsume, std::string_view &chunkEncoded, unsigned int &state) {
10+
void consumeChunkEncoding(int maxConsume, std::string_view &chunkEncoded, uint64_t &state) {
1111
//int maxConsume = 200;
1212

1313
if (uWS::isParsingChunkedEncoding(state)) {
@@ -80,7 +80,7 @@ void runBetterTest(unsigned int maxConsume) {
8080
std::string buffer = ss.str();
8181
std::string_view chunkEncoded = buffer;
8282

83-
unsigned int state = 0;
83+
uint64_t state = 0;
8484

8585
if (uWS::isParsingChunkedEncoding(state)) {
8686
std::abort();
@@ -128,7 +128,7 @@ void runTest(unsigned int maxConsume) {
128128
unsigned int stoppedWithClearState = 0;
129129

130130
/* Begin with a clear state and the full data */
131-
unsigned int state = 0;
131+
uint64_t state = 0;
132132
unsigned int chunkOffset = 0;
133133
std::string_view chunkEncoded = buffer;
134134

@@ -200,7 +200,7 @@ void testWithoutTrailer() {
200200
std::string buffer = ss.str();
201201
std::string_view dataToConsume(buffer.data(), buffer.length());
202202

203-
unsigned int state = uWS::STATE_IS_CHUNKED;
203+
uint64_t state = uWS::STATE_IS_CHUNKED;
204204

205205
for (auto chunk : uWS::ChunkIterator(&dataToConsume, &state)) {
206206

0 commit comments

Comments
 (0)