diff options
author | Eric Andersen <andersen@codepoet.org> | 2000-06-26 12:14:30 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2000-06-26 12:14:30 +0000 |
commit | 1386e7021015959443a3b601b224660848acdda4 (patch) | |
tree | 05cc6c41012fe0f7ff2df50a4ba84d4b5ced4d8f | |
parent | ef40aa81c5024bc305a4e95f6edb76bae258cc2b (diff) | |
download | busybox-w32-1386e7021015959443a3b601b224660848acdda4.tar.gz busybox-w32-1386e7021015959443a3b601b224660848acdda4.tar.bz2 busybox-w32-1386e7021015959443a3b601b224660848acdda4.zip |
Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport.
Fix thanks to Arne Bernin <arne@matrix.loopback.org>
-Erik
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | coreutils/cut.c | 30 | ||||
-rw-r--r-- | cut.c | 30 | ||||
-rw-r--r-- | docs/busybox.pod | 13 |
4 files changed, 55 insertions, 20 deletions
@@ -6,6 +6,8 @@ | |||
6 | * Fixed a nasty bug in tar when could mess up saved symlinks. | 6 | * Fixed a nasty bug in tar when could mess up saved symlinks. |
7 | * Fixed insmod module option parsing for options lacking an '='. | 7 | * Fixed insmod module option parsing for options lacking an '='. |
8 | Fix thanks to Marc Nijdam <marc_nijdam@hp.com> | 8 | Fix thanks to Marc Nijdam <marc_nijdam@hp.com> |
9 | * Fixed segfault with 'cut -f 1 -d:' and added 'cut -s' suport. | ||
10 | Fix thanks to Arne Bernin <arne@matrix.loopback.org> | ||
9 | 11 | ||
10 | -Erik Andersen | 12 | -Erik Andersen |
11 | 13 | ||
diff --git a/coreutils/cut.c b/coreutils/cut.c index 7b183e8fd..a8a9d7fd1 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -51,15 +51,14 @@ int num_args; | |||
51 | #define OPTIONC 2 /* define for mode: option -c */ | 51 | #define OPTIONC 2 /* define for mode: option -c */ |
52 | #define OPTIONB 3 /* define for mode: option -b */ | 52 | #define OPTIONB 3 /* define for mode: option -b */ |
53 | #define NOTSET 0 /* option not selected */ | 53 | #define NOTSET 0 /* option not selected */ |
54 | #define SET 1 /* option selected */ | 54 | #define SET 1 /* option selected */ |
55 | 55 | #define OPTIONS 1 /*define option -s */ | |
56 | /* Defines for the warnings */ | 56 | /* Defines for the warnings */ |
57 | #define DELIMITER_NOT_APPLICABLE 0 | 57 | #define DELIMITER_NOT_APPLICABLE 0 |
58 | #define OVERRIDING_PREVIOUS_MODE 1 | 58 | #define OVERRIDING_PREVIOUS_MODE 1 |
59 | #define OPTION_NOT_APPLICABLE 2 | 59 | #define OPTION_NOT_APPLICABLE 2 |
60 | #define UNKNOWN_OPTION 3 | 60 | #define UNKNOWN_OPTION 3 |
61 | #define FILE_NOT_READABLE 4 | 61 | #define FILE_NOT_READABLE 4 |
62 | |||
63 | /* Defines for the fatal errors */ | 62 | /* Defines for the fatal errors */ |
64 | #define SYNTAX_ERROR 101 | 63 | #define SYNTAX_ERROR 101 |
65 | #define POSITION_ERROR 102 | 64 | #define POSITION_ERROR 102 |
@@ -75,6 +74,7 @@ FILE *fd; | |||
75 | char *name; | 74 | char *name; |
76 | char line[BUFSIZ]; | 75 | char line[BUFSIZ]; |
77 | int exit_status; | 76 | int exit_status; |
77 | int option = 0; /* for -s option */ | ||
78 | 78 | ||
79 | int cut_main(int argc, char **argv); | 79 | int cut_main(int argc, char **argv); |
80 | void warn(int warn_number, char *option); | 80 | void warn(int warn_number, char *option); |
@@ -85,7 +85,7 @@ void cut(void); | |||
85 | void warn(int warn_number, char *option) | 85 | void warn(int warn_number, char *option) |
86 | { | 86 | { |
87 | static char *warn_msg[] = { | 87 | static char *warn_msg[] = { |
88 | "%s: Option -d allowed only with -f\n", | 88 | "%s: Option -%s allowed only with -f\n", |
89 | "%s: -%s overrides earlier option\n", | 89 | "%s: -%s overrides earlier option\n", |
90 | "%s: -%s not allowed in current mode\n", | 90 | "%s: -%s not allowed in current mode\n", |
91 | "%s: Cannot open %s\n" | 91 | "%s: Cannot open %s\n" |
@@ -161,7 +161,8 @@ void cut() | |||
161 | char *columns[MAX_FIELD]; | 161 | char *columns[MAX_FIELD]; |
162 | 162 | ||
163 | while (fgets(line, BUFSIZ, fd)) { | 163 | while (fgets(line, BUFSIZ, fd)) { |
164 | length = strlen(line) - 1; | 164 | maxcol=0; |
165 | length = strlen(line) - 1; | ||
165 | *(line + length) = 0; | 166 | *(line + length) = 0; |
166 | switch (mode) { | 167 | switch (mode) { |
167 | case DUMP_STDIN: | 168 | case DUMP_STDIN: |
@@ -182,11 +183,15 @@ void cut() | |||
182 | for (i = 0; i < num_args; i++) { | 183 | for (i = 0; i < num_args; i++) { |
183 | for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) | 184 | for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) |
184 | if (j <= maxcol) { | 185 | if (j <= maxcol) { |
186 | |||
185 | printf("%s", columns[j - 1]); | 187 | printf("%s", columns[j - 1]); |
188 | |||
186 | if (i != num_args - 1 || j != args[i * 2 + 1]) | 189 | if (i != num_args - 1 || j != args[i * 2 + 1]) |
187 | putchar(delim); | 190 | putchar(delim); |
188 | } | 191 | } |
189 | } | 192 | } |
193 | } else if (option != OPTIONS) { | ||
194 | printf("%s",line); | ||
190 | } | 195 | } |
191 | break; | 196 | break; |
192 | case OPTIONC: | 197 | case OPTIONC: |
@@ -217,7 +222,8 @@ int cut_main(int argc, char **argv) | |||
217 | "Options:\n" | 222 | "Options:\n" |
218 | "\t-b LIST\tOutput only bytes from LIST\n" | 223 | "\t-b LIST\tOutput only bytes from LIST\n" |
219 | "\t-c LIST\tOutput only characters from LIST\n" | 224 | "\t-c LIST\tOutput only characters from LIST\n" |
220 | "\t-d DELIM\tUse DELIM instead of tab as the field delimiter\n" | 225 | "\t-d CHAR\tUse CHAR instead of tab as the field delimiter\n" |
226 | "\t-s\tOnly output Lines if the include DELIM\n" | ||
221 | "\t-f N\tPrint only these fields\n" | 227 | "\t-f N\tPrint only these fields\n" |
222 | "\t-n\tIgnored\n" | 228 | "\t-n\tIgnored\n" |
223 | #endif | 229 | #endif |
@@ -229,7 +235,10 @@ int cut_main(int argc, char **argv) | |||
229 | case 'd': | 235 | case 'd': |
230 | if (mode == OPTIONC || mode == OPTIONB) | 236 | if (mode == OPTIONC || mode == OPTIONB) |
231 | warn(DELIMITER_NOT_APPLICABLE, "d"); | 237 | warn(DELIMITER_NOT_APPLICABLE, "d"); |
232 | delim = argv[i++][0]; | 238 | if (argc > i) |
239 | delim = argv[i++][0]; | ||
240 | else | ||
241 | cuterror(SYNTAX_ERROR); | ||
233 | break; | 242 | break; |
234 | case 'f': | 243 | case 'f': |
235 | sprintf(line, "%s", argv[i++]); | 244 | sprintf(line, "%s", argv[i++]); |
@@ -249,6 +258,10 @@ int cut_main(int argc, char **argv) | |||
249 | warn(OVERRIDING_PREVIOUS_MODE, "c"); | 258 | warn(OVERRIDING_PREVIOUS_MODE, "c"); |
250 | mode = OPTIONC; | 259 | mode = OPTIONC; |
251 | break; | 260 | break; |
261 | case 's': | ||
262 | option = OPTIONS; | ||
263 | |||
264 | break; | ||
252 | case '\0': /* - means: read from stdin */ | 265 | case '\0': /* - means: read from stdin */ |
253 | numberFilenames++; | 266 | numberFilenames++; |
254 | break; | 267 | break; |
@@ -268,6 +281,9 @@ int cut_main(int argc, char **argv) | |||
268 | /* Here follow the checks, if the selected options are reasonable. */ | 281 | /* Here follow the checks, if the selected options are reasonable. */ |
269 | if (mode == OPTIONB) /* since in Minix char := byte */ | 282 | if (mode == OPTIONB) /* since in Minix char := byte */ |
270 | mode = OPTIONC; | 283 | mode = OPTIONC; |
284 | |||
285 | if (mode != OPTIONF && option == OPTIONS) | ||
286 | warn(DELIMITER_NOT_APPLICABLE,"s"); | ||
271 | get_args(); | 287 | get_args(); |
272 | if (numberFilenames != 0) { | 288 | if (numberFilenames != 0) { |
273 | i = 1; | 289 | i = 1; |
@@ -51,15 +51,14 @@ int num_args; | |||
51 | #define OPTIONC 2 /* define for mode: option -c */ | 51 | #define OPTIONC 2 /* define for mode: option -c */ |
52 | #define OPTIONB 3 /* define for mode: option -b */ | 52 | #define OPTIONB 3 /* define for mode: option -b */ |
53 | #define NOTSET 0 /* option not selected */ | 53 | #define NOTSET 0 /* option not selected */ |
54 | #define SET 1 /* option selected */ | 54 | #define SET 1 /* option selected */ |
55 | 55 | #define OPTIONS 1 /*define option -s */ | |
56 | /* Defines for the warnings */ | 56 | /* Defines for the warnings */ |
57 | #define DELIMITER_NOT_APPLICABLE 0 | 57 | #define DELIMITER_NOT_APPLICABLE 0 |
58 | #define OVERRIDING_PREVIOUS_MODE 1 | 58 | #define OVERRIDING_PREVIOUS_MODE 1 |
59 | #define OPTION_NOT_APPLICABLE 2 | 59 | #define OPTION_NOT_APPLICABLE 2 |
60 | #define UNKNOWN_OPTION 3 | 60 | #define UNKNOWN_OPTION 3 |
61 | #define FILE_NOT_READABLE 4 | 61 | #define FILE_NOT_READABLE 4 |
62 | |||
63 | /* Defines for the fatal errors */ | 62 | /* Defines for the fatal errors */ |
64 | #define SYNTAX_ERROR 101 | 63 | #define SYNTAX_ERROR 101 |
65 | #define POSITION_ERROR 102 | 64 | #define POSITION_ERROR 102 |
@@ -75,6 +74,7 @@ FILE *fd; | |||
75 | char *name; | 74 | char *name; |
76 | char line[BUFSIZ]; | 75 | char line[BUFSIZ]; |
77 | int exit_status; | 76 | int exit_status; |
77 | int option = 0; /* for -s option */ | ||
78 | 78 | ||
79 | int cut_main(int argc, char **argv); | 79 | int cut_main(int argc, char **argv); |
80 | void warn(int warn_number, char *option); | 80 | void warn(int warn_number, char *option); |
@@ -85,7 +85,7 @@ void cut(void); | |||
85 | void warn(int warn_number, char *option) | 85 | void warn(int warn_number, char *option) |
86 | { | 86 | { |
87 | static char *warn_msg[] = { | 87 | static char *warn_msg[] = { |
88 | "%s: Option -d allowed only with -f\n", | 88 | "%s: Option -%s allowed only with -f\n", |
89 | "%s: -%s overrides earlier option\n", | 89 | "%s: -%s overrides earlier option\n", |
90 | "%s: -%s not allowed in current mode\n", | 90 | "%s: -%s not allowed in current mode\n", |
91 | "%s: Cannot open %s\n" | 91 | "%s: Cannot open %s\n" |
@@ -161,7 +161,8 @@ void cut() | |||
161 | char *columns[MAX_FIELD]; | 161 | char *columns[MAX_FIELD]; |
162 | 162 | ||
163 | while (fgets(line, BUFSIZ, fd)) { | 163 | while (fgets(line, BUFSIZ, fd)) { |
164 | length = strlen(line) - 1; | 164 | maxcol=0; |
165 | length = strlen(line) - 1; | ||
165 | *(line + length) = 0; | 166 | *(line + length) = 0; |
166 | switch (mode) { | 167 | switch (mode) { |
167 | case DUMP_STDIN: | 168 | case DUMP_STDIN: |
@@ -182,11 +183,15 @@ void cut() | |||
182 | for (i = 0; i < num_args; i++) { | 183 | for (i = 0; i < num_args; i++) { |
183 | for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) | 184 | for (j = args[i * 2]; j <= args[i * 2 + 1]; j++) |
184 | if (j <= maxcol) { | 185 | if (j <= maxcol) { |
186 | |||
185 | printf("%s", columns[j - 1]); | 187 | printf("%s", columns[j - 1]); |
188 | |||
186 | if (i != num_args - 1 || j != args[i * 2 + 1]) | 189 | if (i != num_args - 1 || j != args[i * 2 + 1]) |
187 | putchar(delim); | 190 | putchar(delim); |
188 | } | 191 | } |
189 | } | 192 | } |
193 | } else if (option != OPTIONS) { | ||
194 | printf("%s",line); | ||
190 | } | 195 | } |
191 | break; | 196 | break; |
192 | case OPTIONC: | 197 | case OPTIONC: |
@@ -217,7 +222,8 @@ int cut_main(int argc, char **argv) | |||
217 | "Options:\n" | 222 | "Options:\n" |
218 | "\t-b LIST\tOutput only bytes from LIST\n" | 223 | "\t-b LIST\tOutput only bytes from LIST\n" |
219 | "\t-c LIST\tOutput only characters from LIST\n" | 224 | "\t-c LIST\tOutput only characters from LIST\n" |
220 | "\t-d DELIM\tUse DELIM instead of tab as the field delimiter\n" | 225 | "\t-d CHAR\tUse CHAR instead of tab as the field delimiter\n" |
226 | "\t-s\tOnly output Lines if the include DELIM\n" | ||
221 | "\t-f N\tPrint only these fields\n" | 227 | "\t-f N\tPrint only these fields\n" |
222 | "\t-n\tIgnored\n" | 228 | "\t-n\tIgnored\n" |
223 | #endif | 229 | #endif |
@@ -229,7 +235,10 @@ int cut_main(int argc, char **argv) | |||
229 | case 'd': | 235 | case 'd': |
230 | if (mode == OPTIONC || mode == OPTIONB) | 236 | if (mode == OPTIONC || mode == OPTIONB) |
231 | warn(DELIMITER_NOT_APPLICABLE, "d"); | 237 | warn(DELIMITER_NOT_APPLICABLE, "d"); |
232 | delim = argv[i++][0]; | 238 | if (argc > i) |
239 | delim = argv[i++][0]; | ||
240 | else | ||
241 | cuterror(SYNTAX_ERROR); | ||
233 | break; | 242 | break; |
234 | case 'f': | 243 | case 'f': |
235 | sprintf(line, "%s", argv[i++]); | 244 | sprintf(line, "%s", argv[i++]); |
@@ -249,6 +258,10 @@ int cut_main(int argc, char **argv) | |||
249 | warn(OVERRIDING_PREVIOUS_MODE, "c"); | 258 | warn(OVERRIDING_PREVIOUS_MODE, "c"); |
250 | mode = OPTIONC; | 259 | mode = OPTIONC; |
251 | break; | 260 | break; |
261 | case 's': | ||
262 | option = OPTIONS; | ||
263 | |||
264 | break; | ||
252 | case '\0': /* - means: read from stdin */ | 265 | case '\0': /* - means: read from stdin */ |
253 | numberFilenames++; | 266 | numberFilenames++; |
254 | break; | 267 | break; |
@@ -268,6 +281,9 @@ int cut_main(int argc, char **argv) | |||
268 | /* Here follow the checks, if the selected options are reasonable. */ | 281 | /* Here follow the checks, if the selected options are reasonable. */ |
269 | if (mode == OPTIONB) /* since in Minix char := byte */ | 282 | if (mode == OPTIONB) /* since in Minix char := byte */ |
270 | mode = OPTIONC; | 283 | mode = OPTIONC; |
284 | |||
285 | if (mode != OPTIONF && option == OPTIONS) | ||
286 | warn(DELIMITER_NOT_APPLICABLE,"s"); | ||
271 | get_args(); | 287 | get_args(); |
272 | if (numberFilenames != 0) { | 288 | if (numberFilenames != 0) { |
273 | i = 1; | 289 | i = 1; |
diff --git a/docs/busybox.pod b/docs/busybox.pod index 3f7152ad0..5c2c59054 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod | |||
@@ -276,11 +276,12 @@ Prints selected fields from each input FILE to standard output. | |||
276 | 276 | ||
277 | Options: | 277 | Options: |
278 | 278 | ||
279 | -b LIST Output only bytes from LIST | 279 | -b LIST Output only bytes from LIST |
280 | -c LIST Output only characters from LIST | 280 | -c LIST Output only characters from LIST |
281 | -d DELIM Use DELIM instead of tab as the field delimiter | 281 | -d CHAR Use CHAR instead of tab as the field delimiter |
282 | -f N Print only these fields | 282 | -s Only output Lines if the include DELIM |
283 | -n Ignored | 283 | -f N Print only these fields |
284 | -n Ignored | ||
284 | 285 | ||
285 | Example: | 286 | Example: |
286 | 287 | ||
@@ -2062,4 +2063,4 @@ Enrique Zanardi <ezanardi@ull.es> | |||
2062 | 2063 | ||
2063 | =cut | 2064 | =cut |
2064 | 2065 | ||
2065 | # $Id: busybox.pod,v 1.51 2000/06/21 22:53:24 andersen Exp $ | 2066 | # $Id: busybox.pod,v 1.52 2000/06/26 12:14:30 andersen Exp $ |