diff options
author | Jamie Couture | 2011-09-17 18:25:01 -0400 |
---|---|---|
committer | Lars Hjemli | 2012-01-03 15:16:01 +0000 |
commit | e19f7d7180d64c8ba9ca15f5fe164606f0ec88c1 (patch) | |
tree | 55faa59f4835bec90fa5d94643cf1600d699cdb7 | |
parent | Fix potential XSS vulnerability in rename hint (diff) | |
download | cgit-e19f7d7180d64c8ba9ca15f5fe164606f0ec88c1.tar.gz cgit-e19f7d7180d64c8ba9ca15f5fe164606f0ec88c1.zip |
ui-ssdiff: move LCS table away from the stack
Printing deferred line changes for files containing long lines would cause a segfault. - limit LCS table size: 128x128. - move LCS table to global context: avoid allocating/freeing memory for every deferred line change. Signed-off-by: Jamie Couture <jamie.couture@gmail.com>
-rw-r--r-- | ui-ssdiff.c | 33 | ||||
-rw-r--r-- | ui-ssdiff.h | 12 |
2 files changed, 43 insertions, 2 deletions
diff --git a/ui-ssdiff.c b/ui-ssdiff.c index 2481585..9fb5b11 100644 --- a/ui-ssdiff.c +++ b/ui-ssdiff.c | |||
@@ -2,10 +2,12 @@ | |||
2 | #include "html.h" | 2 | #include "html.h" |
3 | #include "ui-shared.h" | 3 | #include "ui-shared.h" |
4 | #include "ui-diff.h" | 4 | #include "ui-diff.h" |
5 | #include "ui-ssdiff.h" | ||
5 | 6 | ||
6 | extern int use_ssdiff; | 7 | extern int use_ssdiff; |
7 | 8 | ||
8 | static int current_old_line, current_new_line; | 9 | static int current_old_line, current_new_line; |
10 | static int **L = NULL; | ||
9 | 11 | ||
10 | struct deferred_lines { | 12 | struct deferred_lines { |
11 | int line_no; | 13 | int line_no; |
@@ -16,16 +18,42 @@ struct deferred_lines { | |||
16 | static struct deferred_lines *deferred_old, *deferred_old_last; | 18 | static struct deferred_lines *deferred_old, *deferred_old_last; |
17 | static struct deferred_lines *deferred_new, *deferred_new_last; | 19 | static struct deferred_lines *deferred_new, *deferred_new_last; |
18 | 20 | ||
21 | static void create_or_reset_lcs_table() | ||
22 | { | ||
23 | int i; | ||
24 | |||
25 | if (L != NULL) { | ||
26 | memset(*L, 0, sizeof(*L) * MAX_SSDIFF_SIZE); | ||
27 | return; | ||
28 | } | ||
29 | |||
30 | // xcalloc will die if we ran out of memory; | ||
31 | // not very helpful for debugging | ||
32 | L = (int**)xcalloc(MAX_SSDIFF_M, sizeof(int *)); | ||
33 | *L = (int*)xcalloc(MAX_SSDIFF_SIZE, sizeof(int)); | ||
34 | |||
35 | for (i = 1; i < MAX_SSDIFF_M; i++) { | ||
36 | L[i] = *L + i * MAX_SSDIFF_N; | ||
37 | } | ||
38 | } | ||
39 | |||
19 | static char *longest_common_subsequence(char *A, char *B) | 40 | static char *longest_common_subsequence(char *A, char *B) |
20 | { | 41 | { |
21 | int i, j, ri; | 42 | int i, j, ri; |
22 | int m = strlen(A); | 43 | int m = strlen(A); |
23 | int n = strlen(B); | 44 | int n = strlen(B); |
24 | int L[m + 1][n + 1]; | 45 | int tmp1, tmp2, length; |
25 | int tmp1, tmp2; | ||
26 | int lcs_length; | 46 | int lcs_length; |
27 | char *result; | 47 | char *result; |
28 | 48 | ||
49 | length = (m + 1) * (n + 1); | ||
50 | |||
51 | // We bail if the lines are too long | ||
52 | if (length > MAX_SSDIFF_SIZE) | ||
53 | return NULL; | ||
54 | |||
55 | create_or_reset_lcs_table(); | ||
56 | |||
29 | for (i = m; i >= 0; i--) { | 57 | for (i = m; i >= 0; i--) { |
30 | for (j = n; j >= 0; j--) { | 58 | for (j = n; j >= 0; j--) { |
31 | if (A[i] == '\0' || B[j] == '\0') { | 59 | if (A[i] == '\0' || B[j] == '\0') { |
@@ -59,6 +87,7 @@ static char *longest_common_subsequence(char *A, char *B) | |||
59 | j += 1; | 87 | j += 1; |
60 | } | 88 | } |
61 | } | 89 | } |
90 | |||
62 | return result; | 91 | return result; |
63 | } | 92 | } |
64 | 93 | ||
diff --git a/ui-ssdiff.h b/ui-ssdiff.h index 64b4b12..88627e2 100644 --- a/ui-ssdiff.h +++ b/ui-ssdiff.h | |||
@@ -1,6 +1,18 @@ | |||
1 | #ifndef UI_SSDIFF_H | 1 | #ifndef UI_SSDIFF_H |
2 | #define UI_SSDIFF_H | 2 | #define UI_SSDIFF_H |
3 | 3 | ||
4 | /* | ||
5 | * ssdiff line limits | ||
6 | */ | ||
7 | #ifndef MAX_SSDIFF_M | ||
8 | #define MAX_SSDIFF_M 128 | ||
9 | #endif | ||
10 | |||
11 | #ifndef MAX_SSDIFF_N | ||
12 | #define MAX_SSDIFF_N 128 | ||
13 | #endif | ||
14 | #define MAX_SSDIFF_SIZE ((MAX_SSDIFF_M) * (MAX_SSDIFF_N)) | ||
15 | |||
4 | extern void cgit_ssdiff_print_deferred_lines(); | 16 | extern void cgit_ssdiff_print_deferred_lines(); |
5 | 17 | ||
6 | extern void cgit_ssdiff_line_cb(char *line, int len); | 18 | extern void cgit_ssdiff_line_cb(char *line, int len); |