]> git.ipfire.org Git - thirdparty/fcron.git/commitdiff
Fixed fcrondyn printing truncated strings.
authorThibault Godouet <yo8192@users.noreply.github.com>
Sun, 9 Jul 2023 20:51:24 +0000 (21:51 +0100)
committerThibault Godouet <yo8192@users.noreply.github.com>
Sun, 9 Jul 2023 20:51:24 +0000 (21:51 +0100)
fcrondyn.c
fcrondyn_svr.c

index 4199ac5c30cd5175f79603943234578c97077f82..e44e0ff9c1488d3541824b79bd006d7b4f517593 100644 (file)
@@ -581,12 +581,16 @@ talk_fcron(char *cmd_str, int fd)
     while ((read_len = recv(fd, buf, sizeof(buf) - 1, 0)) >= 0
            || errno == EINTR) {
 
+        if (debug_opt) {
+            fprintf(stderr, "read_len=%ld\n", read_len);
+        }
+
         if (errno == EINTR && debug_opt)
             fprintf(stderr, "got EINTR ...\n");
         else if (read_len > sizeof(buf)) {
             /* weird ... no data yet ? */
             if (debug_opt)
-                fprintf(stderr, "no data yet ?");
+                fprintf(stderr, "no data yet ?\n");
         }
         else if (read_len <= 0) {
             if (debug_opt)
@@ -598,13 +602,23 @@ talk_fcron(char *cmd_str, int fd)
         else {
             /* ensure the string is terminated by a '\0' for when we'll printf() it */
             buf[read_len] = '\0';
-            printf("%s", buf);
+
+            int printed_len = 0;
+            while (printed_len < read_len) {
+                int str_len = strlen(buf + printed_len);
+                printf("%s", buf + printed_len);
+                if (str_len > 0 && buf[printed_len+str_len-1] != '\n') {
+                    printf("\n");
+                }
+                printed_len += str_len + 1; /* +1 to account for the end-of-string '\0' marker */
+            }
 
             /* check for the end of command output marker */
             if (read_len >= sizeof(END_STR) &&
-                strncmp(&buf[read_len - sizeof(END_STR)], END_STR,
-                        sizeof(END_STR)) == 0)
+                memcmp(&buf[read_len - sizeof(END_STR)], END_STR,
+                        sizeof(END_STR)) == 0) {
                 break;
+            }
         }
     }
     if (read_len < 0) {
index 9d26d30a859206422bc7f3f4d18b0535be81eb57..b27eae3583cef339b3c87e8b9eeedfddc0913c39 100644 (file)
@@ -362,7 +362,7 @@ auth_client_password(struct fcrondyn_cl *client)
 
 #define Test_add_field(FIELD_NB, FIELD_STR) \
     if ( (bit_test(details, FIELD_NB)) ) { \
-        strncat(fields, FIELD_STR, sizeof(fields)-1 - len); \
+        strncat(fields, FIELD_STR, sizeof(fields) - len -1); \
         len += (sizeof(FIELD_STR)-1); \
     }
 #define Add_field(FIELD_STR) \
@@ -399,9 +399,12 @@ print_fields(int fd, unsigned char *details)
     Add_field(field_cmd);
     Add_field(field_endline);
 
-    fields[TERM_LEN - 1] = '\0';
+    /* Extra safety (which should be redundant as strncat (used in Add_field
+       and Test_add_field) always null-terminate the string: */
+    fields[sizeof(fields) - 1] = '\0';
 
-    if (send(fd, fields, (len < sizeof(fields)) ? len : sizeof(fields), 0) < 0)
+    /* add +1 to include the final end-of-string "\0" */
+    if (send(fd, fields, (len+1 < sizeof(fields)) ? len+1 : sizeof(fields), 0) < 0)
         error_e("error in send()");
 
 }
@@ -471,7 +474,12 @@ print_line(int fd, struct cl_t *line, unsigned char *details, pid_t pid,
     }
     len += snprintf(buf + len, sizeof(buf) - len, "|%s\n", line->cl_shell);
 
-    if (send(fd, buf, (len < sizeof(buf)) ? len : sizeof(buf), 0) < 0)
+    /* as extra safety to make sure the string is always null-terminated
+      (even though snprintf man page suggests it does it already) */
+    buf[sizeof(buf) - 1] = '\0';
+
+    /* add +1 to include the final end-of-string "\0" */
+    if (send(fd, buf, (len+1 < sizeof(buf)) ? len+1 : sizeof(buf), 0) < 0)
         error_e("error in send()");
 
 }
@@ -530,7 +538,7 @@ cmd_ls(struct fcrondyn_cl *client, long int *cmd, int fd, int is_root)
             getloadavg(lavg, 3);
             i = snprintf(lavg_str, sizeof(lavg_str), "Current load average : "
                          "%.1f, %.1f, %.1f\n", lavg[0], lavg[1], lavg[2]);
-            send(fd, lavg_str, i, 0);
+            send(fd, lavg_str, (i+1 < sizeof(lavg_str))? i+1 : sizeof(lavg_str), 0);
 
             bit_set(fields, FIELD_LAVG);
         }