diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/consdiff.c | 11 | ||||
-rw-r--r-- | src/test/test_consdiff.c | 20 |
2 files changed, 30 insertions, 1 deletions
diff --git a/src/or/consdiff.c b/src/or/consdiff.c index d2a2af1b5f..15a614e0fe 100644 --- a/src/or/consdiff.c +++ b/src/or/consdiff.c @@ -671,7 +671,7 @@ gen_ed_diff(const smartlist_t *cons1, const smartlist_t *cons2, */ i1=len1-1, i2=len2-1; char buf[128]; - while (i1 > 0 || i2 > 0) { + while (i1 >= 0 || i2 >= 0) { int start1x, start2x, end1, end2, added, deleted; @@ -795,6 +795,7 @@ apply_ed_diff(const smartlist_t *cons1, const smartlist_t *diff, diff_line[diff_cdline->len] = 0; const char *ptr = diff_line; int start = 0, end = 0; + int had_range = 0; if (get_linenum(&ptr, &start) < 0) { log_warn(LD_CONSDIFF, "Could not apply consensus diff because " "an ed command was missing a line number."); @@ -802,6 +803,7 @@ apply_ed_diff(const smartlist_t *cons1, const smartlist_t *diff, } if (*ptr == ',') { /* Two-item range */ + had_range = 1; ++ptr; if (get_linenum(&ptr, &end) < 0) { log_warn(LD_CONSDIFF, "Could not apply consensus diff because " @@ -850,6 +852,13 @@ apply_ed_diff(const smartlist_t *cons1, const smartlist_t *diff, goto error_cleanup; } + /* 'a' commands are not allowed to have ranges. */ + if (had_range && action == 'a') { + log_warn(LD_CONSDIFF, "Could not apply consensus diff because " + "it wanted to add lines after a range."); + goto error_cleanup; + } + /* Add unchanged lines. */ for (; j && j > end; --j) { cdline_t *cons_line = smartlist_get(cons1, j-1); diff --git a/src/test/test_consdiff.c b/src/test/test_consdiff.c index 1b4e2ad3c1..91986161c9 100644 --- a/src/test/test_consdiff.c +++ b/src/test/test_consdiff.c @@ -622,6 +622,17 @@ test_consdiff_gen_ed_diff(void *arg) tt_str_eq_line(".", smartlist_get(diff, 5)); tt_str_eq_line("2d", smartlist_get(diff, 6)); + smartlist_clear(cons1); + smartlist_clear(cons2); + consensus_split_lines(cons1, "B\n", area); + consensus_split_lines(cons2, "A\nB\n", area); + diff = gen_ed_diff(cons1, cons2, area); + tt_ptr_op(NULL, OP_NE, diff); + tt_int_op(3, OP_EQ, smartlist_len(diff)); + tt_str_eq_line("0a", smartlist_get(diff, 0)); + tt_str_eq_line("A", smartlist_get(diff, 1)); + tt_str_eq_line(".", smartlist_get(diff, 2)); + /* TODO: small real use-cases, i.e. consensuses. */ done: @@ -687,6 +698,15 @@ test_consdiff_apply_ed_diff(void *arg) smartlist_clear(diff); + /* Unexpected range for add command. */ + smartlist_add_linecpy(diff, area, "1,2a"); + mock_clean_saved_logs(); + cons2 = apply_ed_diff(cons1, diff, 0); + tt_ptr_op(NULL, OP_EQ, cons2); + expect_single_log_msg_containing("add lines after a range"); + + smartlist_clear(diff); + /* Script is not in reverse order. */ smartlist_add_linecpy(diff, area, "1d"); smartlist_add_linecpy(diff, area, "3d"); |