static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest);
static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_t *field, void *dest);
static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field, void *dest);
+static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest);
static bool checkreturn pb_skip_varint(pb_istream_t *stream);
static bool checkreturn pb_skip_string(pb_istream_t *stream);
&pb_dec_string,
&pb_dec_submessage,
NULL, /* extensions */
- &pb_dec_bytes /* PB_LTYPE_FIXED_LENGTH_BYTES */
+ &pb_dec_fixed_length_bytes
};
/*******************************
return true;
}
-void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
+bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
{
+ if (substream->bytes_left) {
+ if (!pb_read(substream, NULL, substream->bytes_left))
+ return false;
+ }
+
stream->state = substream->state;
#ifndef PB_NO_ERRMSG
stream->errmsg = substream->errmsg;
#endif
+ return true;
}
/*************************
}
(*size)++;
}
- pb_close_string_substream(stream, &substream);
-
+
if (substream.bytes_left != 0)
PB_RETURN_ERROR(stream, "array overflow");
-
+ if (!pb_close_string_substream(stream, &substream))
+ return false;
+
return status;
}
else
(*size)++;
}
- pb_close_string_substream(stream, &substream);
+ if (!pb_close_string_substream(stream, &substream))
+ return false;
return status;
}
PB_RETURN_ERROR(stream, "callback failed");
} while (substream.bytes_left);
- pb_close_string_substream(stream, &substream);
+ if (!pb_close_string_substream(stream, &substream))
+ return false;
+
return true;
}
else
return false;
status = pb_decode(&substream, fields, dest_struct);
- pb_close_string_substream(stream, &substream);
+
+ if (!pb_close_string_substream(stream, &substream))
+ return false;
return status;
}
}
else
{
- if (PB_LTYPE(field->type) == PB_LTYPE_FIXED_LENGTH_BYTES) {
- if (size != field->data_size)
- PB_RETURN_ERROR(stream, "incorrect inline bytes size");
- return pb_read(stream, (pb_byte_t*)dest, field->data_size);
- }
-
if (alloc_size > field->data_size)
PB_RETURN_ERROR(stream, "bytes overflow");
bdest = (pb_bytes_array_t*)dest;
else
status = pb_decode_noinit(&substream, submsg_fields, dest);
- pb_close_string_substream(stream, &substream);
+ if (!pb_close_string_substream(stream, &substream))
+ return false;
return status;
}
+
+static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_t *field, void *dest)
+{
+ uint32_t size;
+
+ if (!pb_decode_varint32(stream, &size))
+ return false;
+
+ if (size > PB_SIZE_MAX)
+ PB_RETURN_ERROR(stream, "bytes overflow");
+
+ if (size == 0)
+ {
+ /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */
+ memset(dest, 0, field->data_size);
+ return true;
+ }
+
+ if (size != field->data_size)
+ PB_RETURN_ERROR(stream, "incorrect fixed length bytes size");
+
+ return pb_read(stream, (pb_byte_t*)dest, field->data_size);
+}