aboutsummaryrefslogtreecommitdiff
path: root/elegoo/pb/pb_decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'elegoo/pb/pb_decode.c')
-rw-r--r--elegoo/pb/pb_decode.c119
1 files changed, 93 insertions, 26 deletions
diff --git a/elegoo/pb/pb_decode.c b/elegoo/pb/pb_decode.c
index b4563cf..dc344dc 100644
--- a/elegoo/pb/pb_decode.c
+++ b/elegoo/pb/pb_decode.c
@@ -35,6 +35,7 @@ static bool checkreturn find_extension_field(pb_field_iter_t *iter);
static void pb_field_set_to_default(pb_field_iter_t *iter);
static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
+static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof);
static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest);
@@ -52,6 +53,14 @@ static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_it
static void pb_release_single_field(const pb_field_iter_t *iter);
#endif
+#ifdef PB_WITHOUT_64BIT
+#define pb_int64_t int32_t
+#define pb_uint64_t uint32_t
+#else
+#define pb_int64_t int64_t
+#define pb_uint64_t uint64_t
+#endif
+
/* --- Function pointers to field decoders ---
* Order in the array must match pb_action_t LTYPE numbering.
*/
@@ -170,13 +179,23 @@ pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t bufsize)
* Helper functions *
********************/
-bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
+static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof)
{
pb_byte_t byte;
uint32_t result;
if (!pb_readbyte(stream, &byte))
+ {
+ if (stream->bytes_left == 0)
+ {
+ if (eof)
+ {
+ *eof = true;
+ }
+ }
+
return false;
+ }
if ((byte & 0x80) == 0)
{
@@ -191,21 +210,43 @@ bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
do
{
- if (bitpos >= 32)
- PB_RETURN_ERROR(stream, "varint overflow");
-
if (!pb_readbyte(stream, &byte))
return false;
- result |= (uint32_t)(byte & 0x7F) << bitpos;
+ if (bitpos >= 32)
+ {
+ /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */
+ uint8_t sign_extension = (bitpos < 63) ? 0xFF : 0x01;
+
+ if ((byte & 0x7F) != 0x00 && ((result >> 31) == 0 || byte != sign_extension))
+ {
+ PB_RETURN_ERROR(stream, "varint overflow");
+ }
+ }
+ else
+ {
+ result |= (uint32_t)(byte & 0x7F) << bitpos;
+ }
bitpos = (uint_fast8_t)(bitpos + 7);
} while (byte & 0x80);
+
+ if (bitpos == 35 && (byte & 0x70) != 0)
+ {
+ /* The last byte was at bitpos=28, so only bottom 4 bits fit. */
+ PB_RETURN_ERROR(stream, "varint overflow");
+ }
}
*dest = result;
return true;
}
+bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
+{
+ return pb_decode_varint32_eof(stream, dest, NULL);
+}
+
+#ifndef PB_WITHOUT_64BIT
bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
{
pb_byte_t byte;
@@ -227,6 +268,7 @@ bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
*dest = result;
return true;
}
+#endif
bool checkreturn pb_skip_varint(pb_istream_t *stream)
{
@@ -255,11 +297,8 @@ bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type,
*wire_type = (pb_wire_type_t) 0;
*tag = 0;
- if (!pb_decode_varint32(stream, &temp))
+ if (!pb_decode_varint32_eof(stream, &temp, eof))
{
- if (stream->bytes_left == 0)
- *eof = true;
-
return false;
}
@@ -978,6 +1017,21 @@ bool checkreturn pb_decode(pb_istream_t *stream, const pb_field_t fields[], void
return status;
}
+bool pb_decode_delimited_noinit(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
+{
+ pb_istream_t substream;
+ bool status;
+
+ if (!pb_make_string_substream(stream, &substream))
+ return false;
+
+ status = pb_decode_noinit(&substream, fields, dest_struct);
+
+ if (!pb_close_string_substream(stream, &substream))
+ return false;
+ return status;
+}
+
bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
{
pb_istream_t substream;
@@ -993,6 +1047,12 @@ bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *
return status;
}
+bool pb_decode_nullterminated(pb_istream_t *stream, const pb_field_t fields[], void *dest_struct)
+{
+ /* This behaviour will be separated in nanopb-0.4.0, see issue #278. */
+ return pb_decode(stream, fields, dest_struct);
+}
+
#ifdef PB_ENABLE_MALLOC
/* Given an oneof field, if there has already been a field inside this oneof,
* release it before overwriting with a different one. */
@@ -1127,16 +1187,16 @@ void pb_release(const pb_field_t fields[], void *dest_struct)
/* Field decoders */
-bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
+bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest)
{
- uint64_t value;
+ pb_uint64_t value;
if (!pb_decode_varint(stream, &value))
return false;
if (value & 1)
- *dest = (int64_t)(~(value >> 1));
+ *dest = (pb_int64_t)(~(value >> 1));
else
- *dest = (int64_t)(value >> 1);
+ *dest = (pb_int64_t)(value >> 1);
return true;
}
@@ -1155,6 +1215,7 @@ bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
return true;
}
+#ifndef PB_WITHOUT_64BIT
bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
{
pb_byte_t bytes[8];
@@ -1173,12 +1234,13 @@ bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
return true;
}
+#endif
static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
{
- uint64_t value;
- int64_t svalue;
- int64_t clamped;
+ pb_uint64_t value;
+ pb_int64_t svalue;
+ pb_int64_t clamped;
if (!pb_decode_varint(stream, &value))
return false;
@@ -1188,14 +1250,14 @@ static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *fi
* not break decoding of such messages, we cast <=32 bit fields to
* int32_t first to get the sign correct.
*/
- if (field->data_size == sizeof(int64_t))
- svalue = (int64_t)value;
+ if (field->data_size == sizeof(pb_int64_t))
+ svalue = (pb_int64_t)value;
else
svalue = (int32_t)value;
/* Cast to the proper field size, while checking for overflows */
- if (field->data_size == sizeof(int64_t))
- clamped = *(int64_t*)dest = svalue;
+ if (field->data_size == sizeof(pb_int64_t))
+ clamped = *(pb_int64_t*)dest = svalue;
else if (field->data_size == sizeof(int32_t))
clamped = *(int32_t*)dest = (int32_t)svalue;
else if (field->data_size == sizeof(int_least16_t))
@@ -1213,13 +1275,13 @@ static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *fi
static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
{
- uint64_t value, clamped;
+ pb_uint64_t value, clamped;
if (!pb_decode_varint(stream, &value))
return false;
/* Cast to the proper field size, while checking for overflows */
- if (field->data_size == sizeof(uint64_t))
- clamped = *(uint64_t*)dest = value;
+ if (field->data_size == sizeof(pb_uint64_t))
+ clamped = *(pb_uint64_t*)dest = value;
else if (field->data_size == sizeof(uint32_t))
clamped = *(uint32_t*)dest = (uint32_t)value;
else if (field->data_size == sizeof(uint_least16_t))
@@ -1237,13 +1299,13 @@ static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *f
static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
{
- int64_t value, clamped;
+ pb_int64_t value, clamped;
if (!pb_decode_svarint(stream, &value))
return false;
/* Cast to the proper field size, while checking for overflows */
- if (field->data_size == sizeof(int64_t))
- clamped = *(int64_t*)dest = value;
+ if (field->data_size == sizeof(pb_int64_t))
+ clamped = *(pb_int64_t*)dest = value;
else if (field->data_size == sizeof(int32_t))
clamped = *(int32_t*)dest = (int32_t)value;
else if (field->data_size == sizeof(int_least16_t))
@@ -1268,7 +1330,12 @@ static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *f
static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest)
{
PB_UNUSED(field);
+#ifndef PB_WITHOUT_64BIT
return pb_decode_fixed64(stream, dest);
+#else
+ PB_UNUSED(dest);
+ PB_RETURN_ERROR(stream, "no 64bit support");
+#endif
}
static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)