diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-04-14 09:46:39 +0300 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2013-04-14 09:46:39 +0300 |
commit | d2063ff0b63b3b4f2f2081e61874a3c2487c4994 (patch) | |
tree | ad094fd84b4fa329a02cb0be5ddf9198329f0643 | |
parent | 9939910833a9289b5913eff29f951195e7bc61c6 (diff) |
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
-rw-r--r-- | pb_encode.c | 12 | ||||
-rw-r--r-- | tests/encode_unittests.c | 8 | ||||
-rw-r--r-- | tests/unittestproto.proto | 4 |
3 files changed, 19 insertions, 5 deletions
diff --git a/pb_encode.c b/pb_encode.c index 48a3c950..0e048ac6 100644 --- a/pb_encode.c +++ b/pb_encode.c @@ -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) { - UNUSED(field); - return pb_encode_string(stream, (const uint8_t*)src, strlen((const char*)src)); + /* strnlen() is not always available, so just use a for-loop */ + 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) diff --git a/tests/encode_unittests.c b/tests/encode_unittests.c index 3078998e..6a8f5e9e 100644 --- a/tests/encode_unittests.c +++ b/tests/encode_unittests.c @@ -180,12 +180,14 @@ int main() { uint8_t buffer[30]; pb_ostream_t s; - char value[] = "xyzzy"; + char value[30] = "xyzzy"; 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'; - 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")) } { diff --git a/tests/unittestproto.proto b/tests/unittestproto.proto index c8a39dd6..7024942e 100644 --- a/tests/unittestproto.proto +++ b/tests/unittestproto.proto @@ -8,6 +8,10 @@ message FloatArray { repeated float data = 1 [(nanopb).max_count = 10]; } +message StringMessage { + required string data = 1 [(nanopb).max_size = 10]; +} + message CallbackArray { // 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 |