Changed upb status to suit GCC10's warning about strncpy(). (#268)
Added tests for all cases. Also removed ellipses from truncated
messages, they were more trouble than they are worth.
diff --git a/tests/test_generated_code.c b/tests/test_generated_code.c
index a2a4fc0..25fbf77 100644
--- a/tests/test_generated_code.c
+++ b/tests/test_generated_code.c
@@ -7,6 +7,8 @@
#include "tests/upb_test.h"
#include "tests/test.upb.h"
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
const char test_str[] = "abcdefg";
const char test_str2[] = "12345678910";
const char test_str3[] = "rstlnezxcvbnm";
@@ -354,6 +356,36 @@
ASSERT(msg);
protobuf_test_messages_proto3_TestAllTypesProto3_serialize(msg, arena, &size);
ASSERT(size == 0);
+ upb_arena_free(arena);
+}
+
+void test_status_truncation() {
+ int i, j;
+ upb_status status;
+ upb_status status2;
+ for (i = 0; i < UPB_STATUS_MAX_MESSAGE + 20; i++) {
+ char *msg = malloc(i + 1);
+ int end;
+ char ch = (i % 96) + 33; /* Cycle through printable chars. */
+
+ for (j = 0; j < i; j++) {
+ msg[j] = ch;
+ }
+ msg[i] = '\0';
+
+ upb_status_seterrmsg(&status, msg);
+ upb_status_seterrf(&status2, "%s", msg);
+ end = MIN(i, UPB_STATUS_MAX_MESSAGE - 1);
+ ASSERT(strlen(status.msg) == end);
+ ASSERT(strlen(status2.msg) == end);
+
+ for (j = 0; j < end; j++) {
+ ASSERT(status.msg[j] == ch);
+ ASSERT(status2.msg[j] == ch);
+ }
+
+ free(msg);
+ }
}
int run_tests(int argc, char *argv[]) {
@@ -363,5 +395,6 @@
test_int32_map();
test_repeated();
test_null_decode_buf();
+ test_status_truncation();
return 0;
}
diff --git a/upb/upb.c b/upb/upb.c
index cb2cdfd..258192d 100644
--- a/upb/upb.c
+++ b/upb/upb.c
@@ -11,17 +11,6 @@
#include "upb/port_def.inc"
-/* Guarantee null-termination and provide ellipsis truncation.
- * It may be tempting to "optimize" this by initializing these final
- * four bytes up-front and then being careful never to overwrite them,
- * this is safer and simpler. */
-static void nullz(upb_status *status) {
- const char *ellipsis = "...";
- size_t len = strlen(ellipsis);
- UPB_ASSERT(sizeof(status->msg) > len);
- memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
-}
-
/* upb_status *****************************************************************/
void upb_status_clear(upb_status *status) {
@@ -37,8 +26,8 @@
void upb_status_seterrmsg(upb_status *status, const char *msg) {
if (!status) return;
status->ok = false;
- strncpy(status->msg, msg, sizeof(status->msg));
- nullz(status);
+ strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1);
+ status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
}
void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
@@ -52,7 +41,7 @@
if (!status) return;
status->ok = false;
_upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
- nullz(status);
+ status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
}
/* upb_alloc ******************************************************************/