Handle unterminated strings when encoding.
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>
Sun, 14 Apr 2013 06:46:39 +0000 (09:46 +0300)
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>
Sun, 14 Apr 2013 06:46:39 +0000 (09:46 +0300)
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

pb_encode.c
tests/encode_unittests.c
tests/unittestproto.proto

index 48a3c95..0e048ac 100644 (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)
 {
-    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)
index 3078998..6a8f5e9 100644 (file)
@@ -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"))
     }
     
     {
index c8a39dd..7024942 100644 (file)
@@ -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