[gjs] coverage test: Don't use %as specifier in sscanf()



commit 684fd76094344fcf2195769ed13b73531adff9e1
Author: Philip Chimento <philip chimento gmail com>
Date:   Sun Jan 24 13:55:12 2016 -0800

    coverage test: Don't use %as specifier in sscanf()
    
    %as was a GNU extension for automatically allocating a buffer big enough
    to hold whatever string sscanf() found. In C99 %a was defined to be an
    alias of %f, so %as as a GNU extension was deprecated and made unusable.
    It was replaced by another GNU extension, %ms.
    
    However, in the interests of being portable to e.g. BSD, this commit
    avoids using either %as or %ms and instead pre-allocates buffers of at
    least the correct sizes and passes them to sscanf(), using plain old %s.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=761072

 test/gjs-test-coverage.cpp |   34 +++++++++++++++++++++-------------
 1 files changed, 21 insertions(+), 13 deletions(-)
---
diff --git a/test/gjs-test-coverage.cpp b/test/gjs-test-coverage.cpp
index ecd6ffc..2f4f0d8 100644
--- a/test/gjs-test-coverage.cpp
+++ b/test/gjs-test-coverage.cpp
@@ -570,14 +570,19 @@ branch_at_line_should_be_taken(const char *line,
                                gpointer user_data)
 {
     BranchLineData *branch_data = (BranchLineData *) user_data;
-    int line_no, branch_id, block_no, hit_count_num;
-    char *hit_count = NULL;
+    int line_no, branch_id, block_no, hit_count_num, nmatches;
+    char hit_count[20];  /* can hold maxint64 (19 digits) + nul terminator */
 
     /* Advance past "BRDA:" */
     line += 5;
 
-    if (sscanf(line, "%i,%i,%i,%as", &line_no, &block_no, &branch_id, &hit_count) != 4)
-        g_error("sscanf: %s", strerror(errno));
+    nmatches = sscanf(line, "%i,%i,%i,%19s", &line_no, &block_no, &branch_id, &hit_count);
+    if (nmatches != 4) {
+        if (errno != 0)
+            g_error("sscanf: %s", strerror(errno));
+        else
+            g_error("sscanf: only matched %i", nmatches);
+    }
 
     /* Determine the branch hit count. It will be either:
      * > -1 if the line containing the branch was never executed, or
@@ -590,10 +595,6 @@ branch_at_line_should_be_taken(const char *line,
     else
         hit_count_num = atoi(hit_count);
 
-    /* The glibc extension to sscanf dynamically allocates hit_count, so
-     * we need to free it here */
-    free(hit_count);
-
     const gboolean hit_correct_branch_line =
         branch_data->expected_branch_line == line_no;
     const gboolean hit_correct_branch_id =
@@ -938,19 +939,26 @@ hit_count_is_more_than_for_function(const char *line,
     FunctionHitCountData *data = (FunctionHitCountData *) user_data;
     char                 *detected_function = NULL;
     unsigned int         hit_count;
-
+    size_t max_buf_size;
+    int nmatches;
 
     /* Advance past "FNDA:" */
     line += 5;
 
-    if (sscanf(line, "%i,%as", &hit_count, &detected_function) != 2)
-        g_error("sscanf: %s", strerror(errno));
+    max_buf_size = strcspn(line, "\n");
+    detected_function = g_new(char, max_buf_size + 1);
+    nmatches = sscanf(line, "%i,%s", &hit_count, detected_function);
+    if (nmatches != 2) {
+        if (errno != 0)
+            g_error("sscanf: %s", strerror(errno));
+        else
+            g_error("sscanf: only matched %d", nmatches);
+    }
 
     const gboolean function_name_match = g_strcmp0(data->function, detected_function) == 0;
     const gboolean hit_count_more_than = hit_count >= data->hit_count_minimum;
 
-    /* See above, we must free detected_functon */
-    free(detected_function);
+    g_free(detected_function);
 
     return function_name_match &&
            hit_count_more_than;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]