summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/consdiff.c11
-rw-r--r--src/test/test_consdiff.c20
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");