X-Git-Url: https://git.cameronkatri.com/cgit.git/blobdiff_plain/979c460e7f71d153ae79da67b8b21c3412f0fe02..a22855747e97e55a7b7a2622fe671b8ca9af0981:/ui-ssdiff.c diff --git a/ui-ssdiff.c b/ui-ssdiff.c index 2481585..c456033 100644 --- a/ui-ssdiff.c +++ b/ui-ssdiff.c @@ -1,4 +1,5 @@ #include "cgit.h" +#include "ui-ssdiff.h" #include "html.h" #include "ui-shared.h" #include "ui-diff.h" @@ -6,6 +7,7 @@ extern int use_ssdiff; static int current_old_line, current_new_line; +static int **L = NULL; struct deferred_lines { int line_no; @@ -16,16 +18,40 @@ struct deferred_lines { static struct deferred_lines *deferred_old, *deferred_old_last; static struct deferred_lines *deferred_new, *deferred_new_last; +static void create_or_reset_lcs_table(void) +{ + int i; + + if (L != NULL) { + memset(*L, 0, sizeof(int) * MAX_SSDIFF_SIZE); + return; + } + + // xcalloc will die if we ran out of memory; + // not very helpful for debugging + L = (int**)xcalloc(MAX_SSDIFF_M, sizeof(int *)); + *L = (int*)xcalloc(MAX_SSDIFF_SIZE, sizeof(int)); + + for (i = 1; i < MAX_SSDIFF_M; i++) { + L[i] = *L + i * MAX_SSDIFF_N; + } +} + static char *longest_common_subsequence(char *A, char *B) { int i, j, ri; int m = strlen(A); int n = strlen(B); - int L[m + 1][n + 1]; int tmp1, tmp2; int lcs_length; char *result; + // We bail if the lines are too long + if (m >= MAX_SSDIFF_M || n >= MAX_SSDIFF_N) + return NULL; + + create_or_reset_lcs_table(); + for (i = m; i >= 0; i--) { for (j = n; j >= 0; j--) { if (A[i] == '\0' || B[j] == '\0') { @@ -59,13 +85,14 @@ static char *longest_common_subsequence(char *A, char *B) j += 1; } } + return result; } static int line_from_hunk(char *line, char type) { char *buf1, *buf2; - int len; + int len, res; buf1 = strchr(line, type); if (buf1 == NULL) @@ -76,9 +103,8 @@ static int line_from_hunk(char *line, char type) return 0; len = buf2 - buf1; buf2 = xmalloc(len + 1); - strncpy(buf2, buf1, len); - buf2[len] = '\0'; - int res = atoi(buf2); + strlcpy(buf2, buf1, len + 1); + res = atoi(buf2); free(buf2); return res; } @@ -87,11 +113,11 @@ static char *replace_tabs(char *line) { char *prev_buf = line; char *cur_buf; - int linelen = strlen(line); + size_t linelen = strlen(line); int n_tabs = 0; int i; char *result; - char *spaces = " "; + int result_len; if (linelen == 0) { result = xmalloc(1); @@ -99,21 +125,24 @@ static char *replace_tabs(char *line) return result; } - for (i = 0; i < linelen; i++) + for (i = 0; i < linelen; i++) { if (line[i] == '\t') n_tabs += 1; - result = xmalloc(linelen + n_tabs * 8 + 1); + } + result_len = linelen + n_tabs * 8; + result = xmalloc(result_len + 1); result[0] = '\0'; - while (1) { + for (;;) { cur_buf = strchr(prev_buf, '\t'); if (!cur_buf) { - strcat(result, prev_buf); + strncat(result, prev_buf, result_len); break; } else { - strcat(result, " "); - strncat(result, spaces, 8 - (strlen(result) % 8)); strncat(result, prev_buf, cur_buf - prev_buf); + linelen = strlen(result); + memset(&result[linelen], ' ', 8 - (linelen % 8)); + result[linelen + 8 - (linelen % 8)] = '\0'; } prev_buf = cur_buf + 1; } @@ -203,12 +232,14 @@ static void print_ssdiff_line(char *class, if (old_line_no > 0) { struct diff_filespec *old_file = cgit_get_current_old_file(); char *lineno_str = fmt("n%d", old_line_no); - char *id_str = fmt("%s#%s", is_null_sha1(old_file->sha1)?"HEAD":sha1_to_hex(old_rev_sha1), lineno_str); - html("