|
1 | 1 | #include "config.h" |
2 | 2 | #include <ccan/err/err.h> |
3 | 3 | #include <ccan/io/io.h> |
| 4 | +#include <ccan/json_escape/json_escape.h> |
4 | 5 | #include <ccan/read_write_all/read_write_all.h> |
5 | 6 | #include <ccan/str/hex/hex.h> |
6 | 7 | #include <ccan/tal/link/link.h> |
7 | 8 | #include <ccan/tal/str/str.h> |
8 | 9 | #include <common/configvar.h> |
9 | 10 | #include <common/json_command.h> |
10 | | -#include <ccan/json_escape/json_escape.h> |
11 | 11 | #include <common/json_param.h> |
12 | 12 | #include <common/memleak.h> |
13 | 13 | #include <errno.h> |
@@ -558,48 +558,62 @@ static void maybe_notify_log(struct logger *log, |
558 | 558 | notify_log(log->log_book->ld, l); |
559 | 559 | } |
560 | 560 |
|
| 561 | +static void add_one_log_entry(struct logger *log, enum log_level level, |
| 562 | + const struct node_id *node_id, bool call_notifier, |
| 563 | + char *log_msg) |
| 564 | +{ |
| 565 | + struct log_entry *l = new_log_entry(log, level, node_id); |
| 566 | + |
| 567 | + l->log = strdup(log_msg); |
| 568 | + size_t log_len = strlen(l->log); |
| 569 | + |
| 570 | + /* Sanitize any non-printable characters, and replace with '?' |
| 571 | + */ |
| 572 | + for (size_t i = 0; i < log_len; i++) |
| 573 | + if (l->log[i] < ' ' || l->log[i] >= 0x7f) |
| 574 | + l->log[i] = '?'; |
| 575 | + |
| 576 | + maybe_print(log, l); |
| 577 | + maybe_notify_log(log, l); |
| 578 | + |
| 579 | + add_entry(log, &l); |
| 580 | + |
| 581 | + if (call_notifier) |
| 582 | + notify_warning(log->log_book->ld, l); |
| 583 | +} |
| 584 | + |
561 | 585 | void logv(struct logger *log, enum log_level level, |
562 | 586 | const struct node_id *node_id, |
563 | 587 | bool call_notifier, |
564 | 588 | const char *fmt, va_list ap) |
565 | 589 | { |
566 | 590 | int save_errno = errno; |
567 | | - struct log_entry *l = new_log_entry(log, level, node_id); |
| 591 | + char *log_msg = NULL; |
| 592 | + const char *unescaped_log; |
568 | 593 |
|
569 | 594 | /* This is WARN_UNUSED_RESULT, because everyone should somehow deal |
570 | 595 | * with OOM, even though nobody does. */ |
571 | | - if (vasprintf(&l->log, fmt, ap) == -1) |
| 596 | + if (vasprintf(&log_msg, fmt, ap) == -1) |
572 | 597 | abort(); |
573 | 598 |
|
574 | | - tal_t *ctx = tal(NULL, char); |
575 | | - const char *log_line = tal_strdup( |
576 | | - ctx, json_escape_unescape(ctx, (struct json_escape *)l->log)); |
577 | | - char **lines = tal_strsplit(ctx, log_line, "\n", STR_NO_EMPTY); |
578 | | - |
579 | | - /* Split to lines and log them separately. */ |
580 | | - for (size_t i = 0; i < tal_count(lines) - 1; i++) { |
581 | | - struct log_entry *line_entry = |
582 | | - new_log_entry(log, level, node_id); |
583 | | - line_entry->log = tal_strdup(ctx, lines[i]); |
584 | | - |
585 | | - /* Sanitize any non-printable characters, and replace with '?' |
586 | | - */ |
587 | | - size_t line_len = strlen(line_entry->log); |
588 | | - for (size_t i = 0; i < line_len; i++) |
589 | | - if (line_entry->log[i] < ' ' || |
590 | | - line_entry->log[i] >= 0x7f) |
591 | | - line_entry->log[i] = '?'; |
592 | | - |
593 | | - maybe_print(log, line_entry); |
594 | | - maybe_notify_log(log, line_entry); |
595 | | - |
596 | | - add_entry(log, &line_entry); |
| 599 | + /* Nothing to escape: simple copy */ |
| 600 | + if (!strchr(log_msg, '\\')) |
| 601 | + add_one_log_entry(log, level, node_id, call_notifier, log_msg); |
| 602 | + /* If it's weird, unescaping can fail */ |
| 603 | + else if ((unescaped_log = json_escape_unescape( |
| 604 | + tmpctx, (struct json_escape *)log_msg)) == NULL) |
| 605 | + add_one_log_entry(log, level, node_id, call_notifier, log_msg); |
| 606 | + else { |
| 607 | + char **lines = tal_strsplit(unescaped_log, unescaped_log, "\n", |
| 608 | + STR_EMPTY_OK); |
| 609 | + /* Split to lines and log them separately. */ |
| 610 | + for (size_t i = 0; lines[i]; i++) |
| 611 | + add_one_log_entry(log, level, node_id, call_notifier, |
| 612 | + lines[i]); |
597 | 613 | } |
598 | 614 |
|
599 | | - if (call_notifier) |
600 | | - notify_warning(log->log_book->ld, l); |
| 615 | + free(log_msg); |
601 | 616 |
|
602 | | - tal_free(ctx); |
603 | 617 | errno = save_errno; |
604 | 618 | } |
605 | 619 |
|
|
0 commit comments