diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-11 19:07:03 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-11 19:07:03 +0000 |
commit | 6089c2c31e1e9bfaa5b5432758ff3b19128c2ca8 (patch) | |
tree | a3168062055f706daaf229b8beb24520788b9ee5 | |
parent | 6ca0444420223c224162674902d4f6e4e093962d (diff) | |
download | busybox-w32-6089c2c31e1e9bfaa5b5432758ff3b19128c2ca8.tar.gz busybox-w32-6089c2c31e1e9bfaa5b5432758ff3b19128c2ca8.tar.bz2 busybox-w32-6089c2c31e1e9bfaa5b5432758ff3b19128c2ca8.zip |
diff: fix access past end of array
-rw-r--r-- | coreutils/diff.c | 49 |
1 files changed, 13 insertions, 36 deletions
diff --git a/coreutils/diff.c b/coreutils/diff.c index 31c20f052..df43c98ad 100644 --- a/coreutils/diff.c +++ b/coreutils/diff.c | |||
@@ -1044,15 +1044,10 @@ static int add_to_dirlist(const char *filename, | |||
1044 | struct stat ATTRIBUTE_UNUSED * sb, void *userdata, | 1044 | struct stat ATTRIBUTE_UNUSED * sb, void *userdata, |
1045 | int depth ATTRIBUTE_UNUSED) | 1045 | int depth ATTRIBUTE_UNUSED) |
1046 | { | 1046 | { |
1047 | /* +2: with space for eventual trailing NULL */ | ||
1048 | dl = xrealloc(dl, (dl_count+2) * sizeof(dl[0])); | ||
1049 | dl[dl_count] = xstrdup(filename + (int)userdata); | ||
1047 | dl_count++; | 1050 | dl_count++; |
1048 | dl = xrealloc(dl, dl_count * sizeof(char *)); | ||
1049 | dl[dl_count - 1] = xstrdup(filename); | ||
1050 | if (option_mask32 & FLAG_r) { | ||
1051 | int *pp = (int *) userdata; | ||
1052 | int path_len = *pp + 1; | ||
1053 | |||
1054 | dl[dl_count - 1] = &(dl[dl_count - 1])[path_len]; | ||
1055 | } | ||
1056 | return TRUE; | 1051 | return TRUE; |
1057 | } | 1052 | } |
1058 | 1053 | ||
@@ -1060,27 +1055,19 @@ static int add_to_dirlist(const char *filename, | |||
1060 | /* This returns a sorted directory listing. */ | 1055 | /* This returns a sorted directory listing. */ |
1061 | static char **get_dir(char *path) | 1056 | static char **get_dir(char *path) |
1062 | { | 1057 | { |
1063 | int i; | 1058 | dl_count = 0; |
1064 | char **retval; | 1059 | dl = NULL; |
1065 | 1060 | ||
1066 | /* If -r has been set, then the recursive_action function will be | 1061 | /* If -r has been set, then the recursive_action function will be |
1067 | * used. Unfortunately, this outputs the root directory along with | 1062 | * used. Unfortunately, this outputs the root directory along with |
1068 | * the recursed paths, so use void *userdata to specify the string | 1063 | * the recursed paths, so use void *userdata to specify the string |
1069 | * length of the root directory. It can then be removed in | 1064 | * length of the root directory - '(void*)(strlen(path)+)'. |
1070 | * add_to_dirlist. */ | 1065 | * add_to_dirlist then removes root dir prefix. */ |
1071 | |||
1072 | int path_len = strlen(path); | ||
1073 | void *userdata = &path_len; | ||
1074 | 1066 | ||
1075 | /* Reset dl_count - there's no need to free dl as xrealloc does | 1067 | if (option_mask32 & FLAG_r) { |
1076 | * the job nicely. */ | ||
1077 | dl_count = 0; | ||
1078 | |||
1079 | /* Now fill dl with a listing. */ | ||
1080 | if (option_mask32 & FLAG_r) | ||
1081 | recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL, | 1068 | recursive_action(path, TRUE, TRUE, FALSE, add_to_dirlist, NULL, |
1082 | userdata, 0); | 1069 | (void*)(strlen(path)+1), 0); |
1083 | else { | 1070 | } else { |
1084 | DIR *dp; | 1071 | DIR *dp; |
1085 | struct dirent *ep; | 1072 | struct dirent *ep; |
1086 | 1073 | ||
@@ -1088,7 +1075,7 @@ static char **get_dir(char *path) | |||
1088 | while ((ep = readdir(dp))) { | 1075 | while ((ep = readdir(dp))) { |
1089 | if (!strcmp(ep->d_name, "..") || LONE_CHAR(ep->d_name, '.')) | 1076 | if (!strcmp(ep->d_name, "..") || LONE_CHAR(ep->d_name, '.')) |
1090 | continue; | 1077 | continue; |
1091 | add_to_dirlist(ep->d_name, NULL, NULL, 0); | 1078 | add_to_dirlist(ep->d_name, NULL, (void*)(int)0, 0); |
1092 | } | 1079 | } |
1093 | closedir(dp); | 1080 | closedir(dp); |
1094 | } | 1081 | } |
@@ -1096,12 +1083,8 @@ static char **get_dir(char *path) | |||
1096 | /* Sort dl alphabetically. */ | 1083 | /* Sort dl alphabetically. */ |
1097 | qsort(dl, dl_count, sizeof(char *), dir_strcmp); | 1084 | qsort(dl, dl_count, sizeof(char *), dir_strcmp); |
1098 | 1085 | ||
1099 | /* Copy dl so that we can return it. */ | 1086 | dl[dl_count] = NULL; |
1100 | retval = xmalloc(dl_count * sizeof(char *)); | 1087 | return dl; |
1101 | for (i = 0; i < dl_count; i++) | ||
1102 | retval[i] = xstrdup(dl[i]); | ||
1103 | |||
1104 | return retval; | ||
1105 | } | 1088 | } |
1106 | 1089 | ||
1107 | 1090 | ||
@@ -1109,11 +1092,9 @@ static void diffdir(char *p1, char *p2) | |||
1109 | { | 1092 | { |
1110 | char **dirlist1, **dirlist2; | 1093 | char **dirlist1, **dirlist2; |
1111 | char *dp1, *dp2; | 1094 | char *dp1, *dp2; |
1112 | int dirlist1_count, dirlist2_count; | ||
1113 | int pos; | 1095 | int pos; |
1114 | 1096 | ||
1115 | /* Check for trailing slashes. */ | 1097 | /* Check for trailing slashes. */ |
1116 | |||
1117 | dp1 = last_char_is(p1, '/'); | 1098 | dp1 = last_char_is(p1, '/'); |
1118 | if (dp1 != NULL) | 1099 | if (dp1 != NULL) |
1119 | *dp1 = '\0'; | 1100 | *dp1 = '\0'; |
@@ -1124,11 +1105,7 @@ static void diffdir(char *p1, char *p2) | |||
1124 | /* Get directory listings for p1 and p2. */ | 1105 | /* Get directory listings for p1 and p2. */ |
1125 | 1106 | ||
1126 | dirlist1 = get_dir(p1); | 1107 | dirlist1 = get_dir(p1); |
1127 | dirlist1_count = dl_count; | ||
1128 | dirlist1[dirlist1_count] = NULL; | ||
1129 | dirlist2 = get_dir(p2); | 1108 | dirlist2 = get_dir(p2); |
1130 | dirlist2_count = dl_count; | ||
1131 | dirlist2[dirlist2_count] = NULL; | ||
1132 | 1109 | ||
1133 | /* If -S was set, find the starting point. */ | 1110 | /* If -S was set, find the starting point. */ |
1134 | if (start) { | 1111 | if (start) { |