Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address truncation of traces and change MS made to vnsprintf #33

Open
nil-ableton opened this issue Sep 19, 2017 · 0 comments
Open

Address truncation of traces and change MS made to vnsprintf #33

nil-ableton opened this issue Sep 19, 2017 · 0 comments

Comments

@nil-ableton
Copy link
Contributor

Truncation.patch

From 8ca0c5beff5fc1a5ae1b7430c36a872079a41bb6 Mon Sep 17 00:00:00 2001
From: nil <[email protected]>
Date: Tue, 19 Sep 2017 15:46:11 +0200
Subject: [PATCH] Truncate traces that are too large

And move to _vsnprintf on windows to preserve old behavior
---
 src/chars.c         | 21 +++++++++++++++++++--
 src/chars.h         |  6 ++++--
 src/chars_posix.c   |  9 ++++++---
 src/chars_windows.c | 15 +++++++++++----
 src/spdr.c          | 19 +++++++++++++++++++
 5 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/src/chars.c b/src/chars.c
index 1dafd6e..7f38e48 100644
--- a/src/chars.c
+++ b/src/chars.c
@@ -1,8 +1,10 @@
-#include "inlines.h"
 #include "chars.h"
+#include "inlines.h"
 
 #include "uu-stdint.h"
 
+#include <assert.h>
+
 /*
 *	http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
 */
@@ -57,13 +59,14 @@ spdr_internal uint32_t decode(uint32_t *state, uint32_t *codep, uint8_t byte)
 
 spdr_internal void chars_catchar(struct SPDR_Chars *chars, const char c)
 {
-        if (chars->capacity - chars->len < 1) {
+        if (chars->len + 1 >= chars->capacity) {
                 chars->error = 1;
                 return;
         }
 
         chars->chars[chars->len] = c;
         chars->len++;
+        assert(chars->len < chars->capacity);
 }
 
 spdr_internal void chars_catjsonstr(struct SPDR_Chars *chars, const char *utf8)
@@ -112,3 +115,17 @@ spdr_internal void chars_catjsonstr(struct SPDR_Chars *chars, const char *utf8)
         }
 #undef CCODE
 }
+
+spdr_internal void chars_error_clear(struct SPDR_Chars *chars)
+{
+        chars->error = 0;
+}
+
+spdr_internal void chars_truncate(struct SPDR_Chars *chars, int len)
+{
+        if (len >= chars->capacity) {
+                chars->error = 1;
+        }
+        chars->len = len;
+        assert(chars->len < chars->capacity);
+}
diff --git a/src/chars.h b/src/chars.h
index 37d8065..d9459fe 100644
--- a/src/chars.h
+++ b/src/chars.h
@@ -7,8 +7,8 @@
 struct SPDR_Chars {
         uint32_t error;
         char *chars;
-        size_t len;
-        size_t capacity;
+        int len; // @post len < capacity (to reserve one slot for nul terminator
+        int capacity;
 };
 
 #define SPDR_Chars_NULL                                                        \
@@ -16,6 +16,8 @@ struct SPDR_Chars {
                 0, NULL, 0, 0                                                  \
         }
 
+spdr_internal void chars_error_clear(struct SPDR_Chars *chars);
+spdr_internal void chars_truncate(struct SPDR_Chars *chars, int len);
 spdr_internal void
 chars_catsprintf(struct SPDR_Chars *chars, const char *format, ...);
 spdr_internal void chars_catjsonstr(struct SPDR_Chars *chars, const char *utf8);
diff --git a/src/chars_posix.c b/src/chars_posix.c
index 25335d2..1a4424c 100644
--- a/src/chars_posix.c
+++ b/src/chars_posix.c
@@ -1,5 +1,6 @@
 #include "chars.h"
 
+#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 
@@ -16,7 +17,7 @@ chars_catsprintf(struct SPDR_Chars *chars, const char *format, ...)
         }
 
         {
-                size_t remaining_capacity = chars->capacity - chars->len;
+                int remaining_capacity = chars->capacity - chars->len;
                 int result;
                 va_list args;
                 va_start(args, format);
@@ -26,12 +27,14 @@ chars_catsprintf(struct SPDR_Chars *chars, const char *format, ...)
 
                 if (result < 0) {
                         chars->error = 1;
-                } else if ((size_t)result >= remaining_capacity) {
+                } else if (result >= remaining_capacity) {
                         chars->error = 1;
                 } else {
-                        chars->len += (size_t)result;
+                        chars->len += result;
+                        assert(chars->len < chars->capacity);
                 }
 
                 va_end(args);
+                `
         }
 }
diff --git a/src/chars_windows.c b/src/chars_windows.c
index 89cc432..9d7adb7 100644
--- a/src/chars_windows.c
+++ b/src/chars_windows.c
@@ -1,3 +1,4 @@
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
 #include "chars.h"
 
 #include <stdarg.h>
@@ -16,20 +17,26 @@ chars_catsprintf(struct SPDR_Chars *chars, const char *format, ...)
         }
 
         {
+                int remaining_capacity = chars->capacity - chars->len;
                 int count;
                 va_list args;
                 va_start(args, format);
 
-                count =
-                    vsnprintf(chars->chars + chars->len,
-                              chars->capacity - chars->len - 1, format, args);
+                remaining_capacity =
+                    remaining_capacity < 1 ? 0 : remaining_capacity - 1;
+                count = _vsnprintf(chars->chars + chars->len,
+                                   remaining_capacity, format, args);
 
                 if (count < 0) {
                         chars->error = 1;
                 } else {
-                        chars->len += (size_t)count;
+                        chars->len += count;
+                        assert(chars->len < chars->capacity);
                 }
 
                 va_end(args);
         }
 }
+#else
+#include "chars_posix.c"
+#endif
diff --git a/src/spdr.c b/src/spdr.c
index 74ead29..5c290b0 100644
--- a/src/spdr.c
+++ b/src/spdr.c
@@ -381,6 +381,7 @@ spdr_internal void event_log(const struct SPDR_Context *context,
         chars_catsprintf(&buffer, "\"");
         chars_catsprintf(&buffer, " \"%c\"", event->phase);
 
+        int args_start = buffer.len;
         {
                 int arg_i;
                 for (arg_i = 0; arg_i < event->str_count; arg_i++) {
@@ -409,7 +410,15 @@ spdr_internal void event_log(const struct SPDR_Context *context,
                 }
         }
 
+        if (buffer.error) {
+                chars_error_clear(&buffer);
+                chars_truncate(&buffer, args_start);
+                chars_catsprintf(&buffer, " \"ERROR\":\"TruncatedRecord\"");
+        }
+
         if (0 == buffer.error) {
+                assert(buffer.len < buffer.capacity);
+                assert(buffer.chars[buffer.len] == 0);
                 print_fn(buffer.chars, user_data);
         }
 }
@@ -554,6 +563,7 @@ spdr_internal void log_json(const struct SPDR_Context *context,
         chars_catjsonstr(&string, e->name);
         chars_catsprintf(&string, "\"");
         chars_catsprintf(&string, ",\"ph\":\"%c\",\"args\":{", e->phase);
+        int args_start = string.len;
 
         for (i = 0; i < e->str_count; i++) {
                 chars_catsprintf(&string, "%s\"%s\":\"", arg_prefix,
@@ -592,7 +602,16 @@ spdr_internal void log_json(const struct SPDR_Context *context,
         }
         chars_catsprintf(&string, "}");
 
+        if (string.error) {
+                chars_error_clear(&string);
+                chars_truncate(&string, args_start);
+                chars_catsprintf(&string, " \"ERROR\":\"TruncatedRecord\"");
+                chars_catsprintf(&string, "}}");
+        }
+
         if (0 == string.error) {
+                assert(string.len < string.capacity);
+                assert(string.chars[string.len] == 0);
                 print_fn(string.chars, user_data);
         }
 }
-- 
2.14.1.windows.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant