Compare commits

...

7 Commits

Author SHA1 Message Date
Petteri Aimonen
ef741ea530 Publishing nanopb-0.2.1 2013-04-14 10:06:47 +03:00
Petteri Aimonen
26b52b79ad Update changelog 2013-04-14 10:04:46 +03:00
Petteri Aimonen
d2063ff0b6 Handle unterminated strings when encoding.
If the null terminator is not present, string will be limited to the
data size of the field.

If you are still using the pb_enc_string (deprecated since 0.1.3) from
callbacks, now would be an excellent time to stop. The pb_field_t for
the callback will not contain proper data_size. Use pb_encode_string()
instead.

Update issue 68
Status: FixedInGit
2013-04-14 09:46:39 +03:00
Petteri Aimonen
9939910833 Fix bug with empty strings in repeated string callbacks.
Fix suggested by Henrik Carlgren. Added also unit test for the bug.

Update issue 73
Status: FixedInGit
2013-04-14 09:26:42 +03:00
Petteri Aimonen
6a02298584 Avoid maybe-uninitialized warning
Patch from dch.
2013-04-08 11:00:28 +03:00
dch
a968233777 No need to include stdbool.h separately 2013-04-08 10:56:23 +03:00
dch
710465a8e0 __pragma keyword is only supported by recent Microsoft compilers 2013-04-08 10:56:13 +03:00
12 changed files with 68 additions and 16 deletions

View File

@@ -1,3 +1,20 @@
nanopb-0.2.1
NOTE: The default callback function signature has changed.
If you don't want to update your code, define PB_OLD_CALLBACK_STYLE.
Change the callback function to use void** (issue 69)
Add support for defining the nanopb options in a separate file (issue 12)
Add support for packed structs in IAR and MSVC (in addition to GCC) (issue 66)
Implement error message support for the encoder side (issue 7)
Handle unterminated strings when encoding (issue 68)
Fix bug with empty strings in repeated string callbacks (issue 73)
Fix regression in 0.2.0 with optional callback fields (issue 70)
Fix bugs with empty message types (issues 64, 65)
Fix some compiler warnings on clang (issue 67)
Some portability improvements (issues 60, 62)
Various new generator options
Improved tests
nanopb-0.2.0 nanopb-0.2.0
NOTE: This release requires you to regenerate all .pb.c NOTE: This release requires you to regenerate all .pb.c
files. Files generated by older versions will not files. Files generated by older versions will not

View File

@@ -1,5 +1,5 @@
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.''' '''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
nanopb_version = "nanopb-0.2.1-dev" nanopb_version = "nanopb-0.2.1"
try: try:
import google.protobuf.descriptor_pb2 as descriptor import google.protobuf.descriptor_pb2 as descriptor

4
pb.h
View File

@@ -6,7 +6,7 @@
* see pb_encode.h or pb_decode.h * see pb_encode.h or pb_decode.h
*/ */
#define NANOPB_VERSION nanopb-0.2.1-dev #define NANOPB_VERSION nanopb-0.2.1
#ifdef PB_SYSTEM_HEADER #ifdef PB_SYSTEM_HEADER
#include PB_SYSTEM_HEADER #include PB_SYSTEM_HEADER
@@ -30,7 +30,7 @@
# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") # define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)")
# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") # define PB_PACKED_STRUCT_END _Pragma("pack(pop)")
# define pb_packed # define pb_packed
#elif defined(_MSC_VER) #elif defined(_MSC_VER) && (_MSC_VER >= 1500)
/* For Microsoft Visual C++ */ /* For Microsoft Visual C++ */
# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) # define PB_PACKED_STRUCT_START __pragma(pack(push, 1))
# define PB_PACKED_STRUCT_END __pragma(pack(pop)) # define PB_PACKED_STRUCT_END __pragma(pack(pop))

View File

@@ -430,11 +430,11 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type
if (!pb_make_string_substream(stream, &substream)) if (!pb_make_string_substream(stream, &substream))
return false; return false;
while (substream.bytes_left) do
{ {
if (!pCallback->funcs.decode(&substream, iter->pos, arg)) if (!pCallback->funcs.decode(&substream, iter->pos, arg))
PB_RETURN_ERROR(stream, "callback failed"); PB_RETURN_ERROR(stream, "callback failed");
} } while (substream.bytes_left);
pb_close_string_substream(stream, &substream); pb_close_string_substream(stream, &substream);
return true; return true;
@@ -664,7 +664,8 @@ bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest) bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
{ {
uint64_t value; uint64_t value;
bool status = pb_decode_varint(stream, &value); if (!pb_decode_varint(stream, &value))
return false;
switch (field->data_size) switch (field->data_size)
{ {
@@ -675,13 +676,14 @@ bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, vo
default: PB_RETURN_ERROR(stream, "invalid data_size"); default: PB_RETURN_ERROR(stream, "invalid data_size");
} }
return status; return true;
} }
bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest) bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
{ {
int64_t value; int64_t value;
bool status = pb_decode_svarint(stream, &value); if (!pb_decode_svarint(stream, &value))
return false;
switch (field->data_size) switch (field->data_size)
{ {
@@ -690,7 +692,7 @@ bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, v
default: PB_RETURN_ERROR(stream, "invalid data_size"); default: PB_RETURN_ERROR(stream, "invalid data_size");
} }
return status; return true;
} }
bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest) bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest)

View File

@@ -9,7 +9,6 @@
* These are usually generated from .proto-files with a script. * These are usually generated from .proto-files with a script.
*/ */
#include <stdbool.h>
#include "pb.h" #include "pb.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -461,8 +461,16 @@ bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, con
bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src) bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
{ {
UNUSED(field); /* strnlen() is not always available, so just use a for-loop */
return pb_encode_string(stream, (const uint8_t*)src, strlen((const char*)src)); size_t size = 0;
const char *p = (const char*)src;
while (size < field->data_size && *p != '\0')
{
size++;
p++;
}
return pb_encode_string(stream, (const uint8_t*)src, size);
} }
bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src) bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t *field, const void *src)

View File

@@ -6,7 +6,6 @@
* and their field descriptions (just like with pb_decode). * and their field descriptions (just like with pb_decode).
*/ */
#include <stdbool.h>
#include "pb.h" #include "pb.h"
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -11,5 +11,6 @@ message TestMessage {
repeated fixed32 fixed32value = 3; repeated fixed32 fixed32value = 3;
repeated fixed64 fixed64value = 4; repeated fixed64 fixed64value = 4;
optional SubMessage submsg = 5; optional SubMessage submsg = 5;
repeated string repeatedstring = 6;
} }

View File

@@ -180,12 +180,14 @@ int main()
{ {
uint8_t buffer[30]; uint8_t buffer[30];
pb_ostream_t s; pb_ostream_t s;
char value[] = "xyzzy"; char value[30] = "xyzzy";
COMMENT("Test pb_enc_string") COMMENT("Test pb_enc_string")
TEST(WRITES(pb_enc_string(&s, NULL, &value), "\x05xyzzy")) TEST(WRITES(pb_enc_string(&s, &StringMessage_fields[0], &value), "\x05xyzzy"))
value[0] = '\0'; value[0] = '\0';
TEST(WRITES(pb_enc_string(&s, NULL, &value), "\x00")) TEST(WRITES(pb_enc_string(&s, &StringMessage_fields[0], &value), "\x00"))
memset(value, 'x', 30);
TEST(WRITES(pb_enc_string(&s, &StringMessage_fields[0], &value), "\x0Axxxxxxxxxx"))
} }
{ {

View File

@@ -83,6 +83,8 @@ int main()
testmessage.fixed32value.arg = "fixed32value: %ld\n"; testmessage.fixed32value.arg = "fixed32value: %ld\n";
testmessage.fixed64value.funcs.decode = &print_fixed64; testmessage.fixed64value.funcs.decode = &print_fixed64;
testmessage.fixed64value.arg = "fixed64value: %lld\n"; testmessage.fixed64value.arg = "fixed64value: %lld\n";
testmessage.repeatedstring.funcs.decode = &print_string;
testmessage.repeatedstring.arg = "repeatedstring: \"%s\"\n";
if (!pb_decode(&stream, TestMessage_fields, &testmessage)) if (!pb_decode(&stream, TestMessage_fields, &testmessage))
return 1; return 1;

View File

@@ -41,6 +41,22 @@ bool encode_fixed64(pb_ostream_t *stream, const pb_field_t *field, void * const
return pb_encode_fixed64(stream, &value); return pb_encode_fixed64(stream, &value);
} }
bool encode_repeatedstring(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
char *str[4] = {"Hello world!", "", "Test", "Test2"};
int i;
for (i = 0; i < 4; i++)
{
if (!pb_encode_tag_for_field(stream, field))
return false;
if (!pb_encode_string(stream, (uint8_t*)str[i], strlen(str[i])))
return false;
}
return true;
}
int main() int main()
{ {
uint8_t buffer[1024]; uint8_t buffer[1024];
@@ -57,6 +73,8 @@ int main()
testmessage.submsg.int32value.funcs.encode = &encode_int32; testmessage.submsg.int32value.funcs.encode = &encode_int32;
testmessage.submsg.fixed32value.funcs.encode = &encode_fixed32; testmessage.submsg.fixed32value.funcs.encode = &encode_fixed32;
testmessage.submsg.fixed64value.funcs.encode = &encode_fixed64; testmessage.submsg.fixed64value.funcs.encode = &encode_fixed64;
testmessage.repeatedstring.funcs.encode = &encode_repeatedstring;
if (!pb_encode(&stream, TestMessage_fields, &testmessage)) if (!pb_encode(&stream, TestMessage_fields, &testmessage))
return 1; return 1;

View File

@@ -8,6 +8,10 @@ message FloatArray {
repeated float data = 1 [(nanopb).max_count = 10]; repeated float data = 1 [(nanopb).max_count = 10];
} }
message StringMessage {
required string data = 1 [(nanopb).max_size = 10];
}
message CallbackArray { message CallbackArray {
// We cheat a bit and use this message for testing other types, too. // We cheat a bit and use this message for testing other types, too.
// Nanopb does not care about the actual defined data type for callback // Nanopb does not care about the actual defined data type for callback