|
|
@ -763,18 +763,13 @@ extern "C" { |
|
|
|
// this invariant.
|
|
|
|
// this invariant.
|
|
|
|
#define kUpb_EpsCopyInputStream_SlopBytes 16 |
|
|
|
#define kUpb_EpsCopyInputStream_SlopBytes 16 |
|
|
|
|
|
|
|
|
|
|
|
enum { |
|
|
|
|
|
|
|
kUpb_EpsCopyInputStream_NoAliasing = 0, |
|
|
|
|
|
|
|
kUpb_EpsCopyInputStream_OnPatch = 1, |
|
|
|
|
|
|
|
kUpb_EpsCopyInputStream_NoDelta = 2 |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
typedef struct { |
|
|
|
const char* end; // Can read up to SlopBytes bytes beyond this.
|
|
|
|
const char* end; // Can read up to SlopBytes bytes beyond this.
|
|
|
|
const char* limit_ptr; // For bounds checks, = end + UPB_MIN(limit, 0)
|
|
|
|
const char* limit_ptr; // For bounds checks, = end + UPB_MIN(limit, 0)
|
|
|
|
uintptr_t aliasing; |
|
|
|
uintptr_t input_delta; // Diff between the original input pointer and patch
|
|
|
|
int limit; // Submessage limit relative to end
|
|
|
|
int limit; // Submessage limit relative to end
|
|
|
|
bool error; // To distinguish between EOF and error.
|
|
|
|
bool error; // To distinguish between EOF and error.
|
|
|
|
|
|
|
|
bool aliasing; |
|
|
|
char patch[kUpb_EpsCopyInputStream_SlopBytes * 2]; |
|
|
|
char patch[kUpb_EpsCopyInputStream_SlopBytes * 2]; |
|
|
|
} upb_EpsCopyInputStream; |
|
|
|
} upb_EpsCopyInputStream; |
|
|
|
|
|
|
|
|
|
|
@ -800,17 +795,16 @@ UPB_INLINE void upb_EpsCopyInputStream_Init(upb_EpsCopyInputStream* e, |
|
|
|
if (size <= kUpb_EpsCopyInputStream_SlopBytes) { |
|
|
|
if (size <= kUpb_EpsCopyInputStream_SlopBytes) { |
|
|
|
memset(&e->patch, 0, 32); |
|
|
|
memset(&e->patch, 0, 32); |
|
|
|
if (size) memcpy(&e->patch, *ptr, size); |
|
|
|
if (size) memcpy(&e->patch, *ptr, size); |
|
|
|
e->aliasing = enable_aliasing ? (uintptr_t)*ptr - (uintptr_t)e->patch |
|
|
|
e->input_delta = (uintptr_t)*ptr - (uintptr_t)e->patch; |
|
|
|
: kUpb_EpsCopyInputStream_NoAliasing; |
|
|
|
|
|
|
|
*ptr = e->patch; |
|
|
|
*ptr = e->patch; |
|
|
|
e->end = *ptr + size; |
|
|
|
e->end = *ptr + size; |
|
|
|
e->limit = 0; |
|
|
|
e->limit = 0; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
e->end = *ptr + size - kUpb_EpsCopyInputStream_SlopBytes; |
|
|
|
e->end = *ptr + size - kUpb_EpsCopyInputStream_SlopBytes; |
|
|
|
e->limit = kUpb_EpsCopyInputStream_SlopBytes; |
|
|
|
e->limit = kUpb_EpsCopyInputStream_SlopBytes; |
|
|
|
e->aliasing = enable_aliasing ? kUpb_EpsCopyInputStream_NoDelta |
|
|
|
e->input_delta = 0; |
|
|
|
: kUpb_EpsCopyInputStream_NoAliasing; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
e->aliasing = enable_aliasing; |
|
|
|
e->limit_ptr = e->end; |
|
|
|
e->limit_ptr = e->end; |
|
|
|
e->error = false; |
|
|
|
e->error = false; |
|
|
|
} |
|
|
|
} |
|
|
@ -953,7 +947,7 @@ UPB_INLINE bool upb_EpsCopyInputStream_CheckSubMessageSizeAvailable( |
|
|
|
// upb_EpsCopyInputStream_Init() when this stream was initialized.
|
|
|
|
// upb_EpsCopyInputStream_Init() when this stream was initialized.
|
|
|
|
UPB_INLINE bool upb_EpsCopyInputStream_AliasingEnabled( |
|
|
|
UPB_INLINE bool upb_EpsCopyInputStream_AliasingEnabled( |
|
|
|
upb_EpsCopyInputStream* e) { |
|
|
|
upb_EpsCopyInputStream* e) { |
|
|
|
return e->aliasing != kUpb_EpsCopyInputStream_NoAliasing; |
|
|
|
return e->aliasing; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Returns true if aliasing_enabled=true was passed to
|
|
|
|
// Returns true if aliasing_enabled=true was passed to
|
|
|
@ -963,8 +957,16 @@ UPB_INLINE bool upb_EpsCopyInputStream_AliasingAvailable( |
|
|
|
upb_EpsCopyInputStream* e, const char* ptr, size_t size) { |
|
|
|
upb_EpsCopyInputStream* e, const char* ptr, size_t size) { |
|
|
|
// When EpsCopyInputStream supports streaming, this will need to become a
|
|
|
|
// When EpsCopyInputStream supports streaming, this will need to become a
|
|
|
|
// runtime check.
|
|
|
|
// runtime check.
|
|
|
|
return upb_EpsCopyInputStream_CheckDataSizeAvailable(e, ptr, size) && |
|
|
|
return e->aliasing && |
|
|
|
e->aliasing >= kUpb_EpsCopyInputStream_NoDelta; |
|
|
|
upb_EpsCopyInputStream_CheckDataSizeAvailable(e, ptr, size); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Returns a pointer into an input buffer that corresponds to the parsing
|
|
|
|
|
|
|
|
// pointer `ptr`. The returned pointer may be the same as `ptr`, but also may
|
|
|
|
|
|
|
|
// be different if we are currently parsing out of the patch buffer.
|
|
|
|
|
|
|
|
UPB_INLINE const char* upb_EpsCopyInputStream_GetInputPtr( |
|
|
|
|
|
|
|
upb_EpsCopyInputStream* e, const char* ptr) { |
|
|
|
|
|
|
|
return (const char*)(((uintptr_t)ptr) + e->input_delta); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Returns a pointer into an input buffer that corresponds to the parsing
|
|
|
|
// Returns a pointer into an input buffer that corresponds to the parsing
|
|
|
@ -976,9 +978,7 @@ UPB_INLINE bool upb_EpsCopyInputStream_AliasingAvailable( |
|
|
|
UPB_INLINE const char* upb_EpsCopyInputStream_GetAliasedPtr( |
|
|
|
UPB_INLINE const char* upb_EpsCopyInputStream_GetAliasedPtr( |
|
|
|
upb_EpsCopyInputStream* e, const char* ptr) { |
|
|
|
upb_EpsCopyInputStream* e, const char* ptr) { |
|
|
|
UPB_ASSUME(upb_EpsCopyInputStream_AliasingAvailable(e, ptr, 0)); |
|
|
|
UPB_ASSUME(upb_EpsCopyInputStream_AliasingAvailable(e, ptr, 0)); |
|
|
|
uintptr_t delta = |
|
|
|
return upb_EpsCopyInputStream_GetInputPtr(e, ptr); |
|
|
|
e->aliasing == kUpb_EpsCopyInputStream_NoDelta ? 0 : e->aliasing; |
|
|
|
|
|
|
|
return (const char*)((uintptr_t)ptr + delta); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Reads string data from the input, aliasing into the input buffer instead of
|
|
|
|
// Reads string data from the input, aliasing into the input buffer instead of
|
|
|
@ -1092,9 +1092,7 @@ UPB_INLINE const char* _upb_EpsCopyInputStream_IsDoneFallbackInline( |
|
|
|
e->limit -= kUpb_EpsCopyInputStream_SlopBytes; |
|
|
|
e->limit -= kUpb_EpsCopyInputStream_SlopBytes; |
|
|
|
e->limit_ptr = e->end + e->limit; |
|
|
|
e->limit_ptr = e->end + e->limit; |
|
|
|
UPB_ASSERT(ptr < e->limit_ptr); |
|
|
|
UPB_ASSERT(ptr < e->limit_ptr); |
|
|
|
if (e->aliasing != kUpb_EpsCopyInputStream_NoAliasing) { |
|
|
|
e->input_delta = (uintptr_t)old_end - (uintptr_t)new_start; |
|
|
|
e->aliasing = (uintptr_t)old_end - (uintptr_t)new_start; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return callback(e, old_end, new_start); |
|
|
|
return callback(e, old_end, new_start); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
UPB_ASSERT(overrun > e->limit); |
|
|
|
UPB_ASSERT(overrun > e->limit); |
|
|
@ -14267,17 +14265,18 @@ enum { |
|
|
|
#ifndef UPB_WIRE_INTERNAL_DECODER_H_ |
|
|
|
#ifndef UPB_WIRE_INTERNAL_DECODER_H_ |
|
|
|
#define UPB_WIRE_INTERNAL_DECODER_H_ |
|
|
|
#define UPB_WIRE_INTERNAL_DECODER_H_ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <stddef.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "utf8_range.h" |
|
|
|
#include "utf8_range.h" |
|
|
|
|
|
|
|
|
|
|
|
// Must be last.
|
|
|
|
// Must be last.
|
|
|
|
|
|
|
|
|
|
|
|
#define DECODE_NOGROUP (uint32_t) - 1 |
|
|
|
#define DECODE_NOGROUP (uint32_t)-1 |
|
|
|
|
|
|
|
|
|
|
|
typedef struct upb_Decoder { |
|
|
|
typedef struct upb_Decoder { |
|
|
|
upb_EpsCopyInputStream input; |
|
|
|
upb_EpsCopyInputStream input; |
|
|
|
const upb_ExtensionRegistry* extreg; |
|
|
|
const upb_ExtensionRegistry* extreg; |
|
|
|
const char* unknown; // Start of unknown data, preserve at buffer flip
|
|
|
|
upb_Message* original_msg; // Pointer to preserve data to
|
|
|
|
upb_Message* unknown_msg; // Pointer to preserve data to
|
|
|
|
|
|
|
|
int depth; // Tracks recursion depth to bound stack usage.
|
|
|
|
int depth; // Tracks recursion depth to bound stack usage.
|
|
|
|
uint32_t end_group; // field number of END_GROUP tag, else DECODE_NOGROUP.
|
|
|
|
uint32_t end_group; // field number of END_GROUP tag, else DECODE_NOGROUP.
|
|
|
|
uint16_t options; |
|
|
|
uint16_t options; |
|
|
@ -14337,14 +14336,6 @@ UPB_INLINE const char* _upb_Decoder_BufferFlipCallback( |
|
|
|
upb_EpsCopyInputStream* e, const char* old_end, const char* new_start) { |
|
|
|
upb_EpsCopyInputStream* e, const char* old_end, const char* new_start) { |
|
|
|
upb_Decoder* d = (upb_Decoder*)e; |
|
|
|
upb_Decoder* d = (upb_Decoder*)e; |
|
|
|
if (!old_end) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); |
|
|
|
if (!old_end) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); |
|
|
|
|
|
|
|
|
|
|
|
if (d->unknown) { |
|
|
|
|
|
|
|
if (!UPB_PRIVATE(_upb_Message_AddUnknown)( |
|
|
|
|
|
|
|
d->unknown_msg, d->unknown, old_end - d->unknown, &d->arena)) { |
|
|
|
|
|
|
|
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
d->unknown = new_start; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return new_start; |
|
|
|
return new_start; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|