[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
grep branch, master, updated. v2.10-85-g8fcf615
From: |
Paul Eggert |
Subject: |
grep branch, master, updated. v2.10-85-g8fcf615 |
Date: |
Thu, 01 Mar 2012 15:46:25 +0000 |
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "grep".
The branch, master has been updated
via 8fcf61523644df42e1905c81bed26838e0b04f91 (commit)
via 4572ea4649d025e51463d48c2d06a1c66134cdb8 (commit)
via a19dc139056aaf09137991bacef364c8fef60168 (commit)
via cbbc1a45b9f843c811905c97c90a5d31f8e6c189 (commit)
via 235aad711285fc6978f6ff26397743930b23f79a (commit)
from 3732fd2b98692a1e58fa7254fc0cacab8136fb11 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/grep.git/commit/?id=8fcf61523644df42e1905c81bed26838e0b04f91
commit 8fcf61523644df42e1905c81bed26838e0b04f91
Author: Paul Eggert <address@hidden>
Date: Wed Feb 29 00:49:40 2012 -0800
grep: fix integer-overflow issues in main program
* NEWS: Document this.
* bootstrap.conf (gnulib_modules): Add inttypes, xstrtoimax.
Remove xstrtoumax.
* src/main.c: Include <inttypes.h>, for INTMAX_MAX, PRIdMAX.
(context_length_arg, prtext, grepbuf, grep, grepfile)
(get_nondigit_option, main):
Use intmax_t, not int, for line counts.
(context_length_arg, main): Silently ceiling line counts
to maximum value, since there's no practical difference between
doing that and using infinite-precision arithmetic.
(out_before, out_after, pending): Now intmax_t, not int.
(max_count, outleft): Now intmax_t, not off_t.
(prepend_args, prepend_default_options, main):
Use size_t, not int, for sizes.
(prepend_default_options): Check for int and size_t overflow.
diff --git a/NEWS b/NEWS
index 47e0ca4..5ff4027 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ GNU grep NEWS -*- outline
-*-
GNU C library's regular expression functions cannot handle such long lines.
[bug present since "the beginning"]
+ The -m, -A, -B, and -C options no longer mishandle context line
+ counts that do not fit in 'int'. Also, grep -c's counts are now
+ limited by the type 'intmax_t' (typically less than 2**63) rather
+ than 'int' (typically less than 2**31).
+
grep no longer silently suppresses errors when reading a directory
as if it were a text file. For example, "grep x ." now reports a
read error on most systems; formerly, it ignored the error.
diff --git a/bootstrap.conf b/bootstrap.conf
index 2b7a5ec..45bb33d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -41,6 +41,7 @@ gnupload
hard-locale
ignore-value
intprops
+inttypes
isatty
isblank
isdir
@@ -85,7 +86,7 @@ wcscoll
wctob
wctype-h
xalloc
-xstrtoumax
+xstrtoimax
'
gnulib_name=libgreputils
diff --git a/src/main.c b/src/main.c
index 3c5f6dd..7d83f4d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include "system.h"
@@ -425,17 +426,21 @@ clean_up_stdout (void)
close_stdout ();
}
-/* Convert STR to a positive integer, storing the result in *OUT.
+/* Convert STR to a nonnegative integer, storing the result in *OUT.
STR must be a valid context length argument; report an error if it
- isn't. */
+ isn't. Silently ceiling *OUT at the maximum value, as that is
+ practically equivalent to infinity for grep's purposes. */
static void
-context_length_arg (char const *str, int *out)
+context_length_arg (char const *str, intmax_t *out)
{
- uintmax_t value;
- if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK
- && 0 <= (*out = value)
- && *out == value))
+ switch (xstrtoimax (str, 0, 10, out, ""))
{
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ if (0 <= *out)
+ break;
+ /* Fall through. */
+ default:
error (EXIT_TROUBLE, 0, "%s: %s", str,
_("invalid context length argument"));
}
@@ -603,12 +608,12 @@ static int out_invert; /* Print nonmatching
stuff. */
static int out_file; /* Print filenames. */
static int out_line; /* Print line numbers. */
static int out_byte; /* Print byte offsets. */
-static int out_before; /* Lines of leading context. */
-static int out_after; /* Lines of trailing context. */
+static intmax_t out_before; /* Lines of leading context. */
+static intmax_t out_after; /* Lines of trailing context. */
static int count_matches; /* Count matching lines. */
static int list_files; /* List matching files. */
static int no_filenames; /* Suppress file names. */
-static off_t max_count; /* Stop after outputting this many
+static intmax_t max_count; /* Stop after outputting this many
lines from an input file. */
static int line_buffered; /* If nonzero, use line buffering, i.e.
fflush everyline out. */
@@ -622,8 +627,8 @@ static char const *lastout; /* Pointer after last character
output;
NULL if no character has been output
or if it's conceptually before bufbeg. */
static uintmax_t totalnl; /* Total newline count before lastnl. */
-static off_t outleft; /* Maximum number of lines to be output. */
-static int pending; /* Pending lines of output.
+static intmax_t outleft; /* Maximum number of lines to be output. */
+static intmax_t pending; /* Pending lines of output.
Always kept 0 if out_quiet is true. */
static int done_on_match; /* Stop scanning file on first match. */
static int exit_on_match; /* Exit on first match. */
@@ -917,12 +922,12 @@ prpending (char const *lim)
/* Print the lines between BEG and LIM. Deal with context crap.
If NLINESP is non-null, store a count of lines between BEG and LIM. */
static void
-prtext (char const *beg, char const *lim, int *nlinesp)
+prtext (char const *beg, char const *lim, intmax_t *nlinesp)
{
static int used; /* avoid printing SEP_STR_GROUP before any output */
char const *bp, *p;
char eol = eolbyte;
- int i, n;
+ intmax_t i, n;
if (!out_quiet && pending > 0)
prpending (beg);
@@ -1026,10 +1031,10 @@ do_execute (char const *buf, size_t size, size_t
*match_size, char const *start_
/* Scan the specified portion of the buffer, matching lines (or
between matching lines if OUT_INVERT is true). Return a count of
lines printed. */
-static int
+static intmax_t
grepbuf (char const *beg, char const *lim)
{
- int nlines, n;
+ intmax_t nlines, n;
char const *p;
size_t match_offset;
size_t match_size;
@@ -1046,7 +1051,7 @@ grepbuf (char const *beg, char const *lim)
break;
if (!out_invert)
{
- prtext (b, endp, (int *) 0);
+ prtext (b, endp, NULL);
nlines++;
outleft--;
if (!outleft || done_on_match)
@@ -1079,10 +1084,10 @@ grepbuf (char const *beg, char const *lim)
/* Search a given file. Normally, return a count of lines printed;
but if the file is a directory and we search it recursively, then
return -2 if there was a match, and -1 otherwise. */
-static int
+static intmax_t
grep (int fd, char const *file, struct stats *stats)
{
- int nlines, i;
+ intmax_t nlines, i;
int not_text;
size_t residue, save;
char oldc;
@@ -1212,7 +1217,7 @@ static int
grepfile (char const *file, struct stats *stats)
{
int desc;
- int count;
+ intmax_t count;
int status;
filename = (file ? file : label ? label : _("(standard input)"));
@@ -1319,7 +1324,7 @@ grepfile (char const *file, struct stats *stats)
else
fputc (0, stdout);
}
- printf ("%d\n", count);
+ printf ("%" PRIdMAX "\n", count);
}
status = !count;
@@ -1590,12 +1595,12 @@ setmatcher (char const *m)
etc. to the option copies. Return the number N of options found.
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
etc. Backslash can be used to escape whitespace (and backslashes). */
-static int
+static size_t
prepend_args (char const *options, char *buf, char **argv)
{
char const *o = options;
char *b = buf;
- int n = 0;
+ size_t n = 0;
for (;;)
{
@@ -1625,10 +1630,14 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
if (options && *options)
{
char *buf = xmalloc (strlen (options) + 1);
- int prepended = prepend_args (options, buf, (char **) NULL);
+ size_t prepended = prepend_args (options, buf, NULL);
int argc = *pargc;
char *const *argv = *pargv;
- char **pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
+ char **pp;
+ enum { MAX_ARGS = MIN (INT_MAX, SIZE_MAX / sizeof *pp - 1) };
+ if (MAX_ARGS - argc < prepended)
+ xalloc_die ();
+ pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
*pargc = prepended + argc;
*pargv = pp;
*pp++ = *argv++;
@@ -1646,11 +1655,11 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
Process any digit options that were encountered on the way,
and store the resulting integer into *DEFAULT_CONTEXT. */
static int
-get_nondigit_option (int argc, char *const *argv, int *default_context)
+get_nondigit_option (int argc, char *const *argv, intmax_t *default_context)
{
static int prev_digit_optind = -1;
int opt, this_digit_optind, was_digit;
- char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
+ char buf[INT_BUFSIZE_BOUND (intmax_t) + 4];
char *p = buf;
was_digit = 0;
@@ -1760,11 +1769,11 @@ main (int argc, char **argv)
char *keys;
size_t keycc, oldcc, keyalloc;
int with_filenames;
- int opt, cc, status, prepended;
+ size_t cc;
+ int opt, status, prepended;
int prev_optind, last_recursive;
- int default_context;
+ intmax_t default_context;
FILE *fp;
-
exit_failure = EXIT_TROUBLE;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1776,7 +1785,7 @@ main (int argc, char **argv)
eolbyte = '\n';
filename_mask = ~0;
- max_count = TYPE_MAXIMUM (off_t);
+ max_count = INTMAX_MAX;
/* The value -1 means to use DEFAULT_CONTEXT. */
out_after = out_before = -1;
@@ -1947,23 +1956,15 @@ main (int argc, char **argv)
break;
case 'm':
- {
- uintmax_t value;
- switch (xstrtoumax (optarg, 0, 10, &value, ""))
- {
- case LONGINT_OK:
- max_count = value;
- if (0 <= max_count && max_count == value)
- break;
- /* Fall through. */
- case LONGINT_OVERFLOW:
- max_count = TYPE_MAXIMUM (off_t);
- break;
+ switch (xstrtoimax (optarg, 0, 10, &max_count, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ break;
- default:
- error (EXIT_TROUBLE, 0, _("invalid max count"));
- }
- }
+ default:
+ error (EXIT_TROUBLE, 0, _("invalid max count"));
+ }
break;
case 'n':
http://git.savannah.gnu.org/cgit/grep.git/commit/?id=4572ea4649d025e51463d48c2d06a1c66134cdb8
commit 8fcf61523644df42e1905c81bed26838e0b04f91
Author: Paul Eggert <address@hidden>
Date: Wed Feb 29 00:49:40 2012 -0800
grep: fix integer-overflow issues in main program
* NEWS: Document this.
* bootstrap.conf (gnulib_modules): Add inttypes, xstrtoimax.
Remove xstrtoumax.
* src/main.c: Include <inttypes.h>, for INTMAX_MAX, PRIdMAX.
(context_length_arg, prtext, grepbuf, grep, grepfile)
(get_nondigit_option, main):
Use intmax_t, not int, for line counts.
(context_length_arg, main): Silently ceiling line counts
to maximum value, since there's no practical difference between
doing that and using infinite-precision arithmetic.
(out_before, out_after, pending): Now intmax_t, not int.
(max_count, outleft): Now intmax_t, not off_t.
(prepend_args, prepend_default_options, main):
Use size_t, not int, for sizes.
(prepend_default_options): Check for int and size_t overflow.
diff --git a/NEWS b/NEWS
index 47e0ca4..5ff4027 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ GNU grep NEWS -*- outline
-*-
GNU C library's regular expression functions cannot handle such long lines.
[bug present since "the beginning"]
+ The -m, -A, -B, and -C options no longer mishandle context line
+ counts that do not fit in 'int'. Also, grep -c's counts are now
+ limited by the type 'intmax_t' (typically less than 2**63) rather
+ than 'int' (typically less than 2**31).
+
grep no longer silently suppresses errors when reading a directory
as if it were a text file. For example, "grep x ." now reports a
read error on most systems; formerly, it ignored the error.
diff --git a/bootstrap.conf b/bootstrap.conf
index 2b7a5ec..45bb33d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -41,6 +41,7 @@ gnupload
hard-locale
ignore-value
intprops
+inttypes
isatty
isblank
isdir
@@ -85,7 +86,7 @@ wcscoll
wctob
wctype-h
xalloc
-xstrtoumax
+xstrtoimax
'
gnulib_name=libgreputils
diff --git a/src/main.c b/src/main.c
index 3c5f6dd..7d83f4d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include "system.h"
@@ -425,17 +426,21 @@ clean_up_stdout (void)
close_stdout ();
}
-/* Convert STR to a positive integer, storing the result in *OUT.
+/* Convert STR to a nonnegative integer, storing the result in *OUT.
STR must be a valid context length argument; report an error if it
- isn't. */
+ isn't. Silently ceiling *OUT at the maximum value, as that is
+ practically equivalent to infinity for grep's purposes. */
static void
-context_length_arg (char const *str, int *out)
+context_length_arg (char const *str, intmax_t *out)
{
- uintmax_t value;
- if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK
- && 0 <= (*out = value)
- && *out == value))
+ switch (xstrtoimax (str, 0, 10, out, ""))
{
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ if (0 <= *out)
+ break;
+ /* Fall through. */
+ default:
error (EXIT_TROUBLE, 0, "%s: %s", str,
_("invalid context length argument"));
}
@@ -603,12 +608,12 @@ static int out_invert; /* Print nonmatching
stuff. */
static int out_file; /* Print filenames. */
static int out_line; /* Print line numbers. */
static int out_byte; /* Print byte offsets. */
-static int out_before; /* Lines of leading context. */
-static int out_after; /* Lines of trailing context. */
+static intmax_t out_before; /* Lines of leading context. */
+static intmax_t out_after; /* Lines of trailing context. */
static int count_matches; /* Count matching lines. */
static int list_files; /* List matching files. */
static int no_filenames; /* Suppress file names. */
-static off_t max_count; /* Stop after outputting this many
+static intmax_t max_count; /* Stop after outputting this many
lines from an input file. */
static int line_buffered; /* If nonzero, use line buffering, i.e.
fflush everyline out. */
@@ -622,8 +627,8 @@ static char const *lastout; /* Pointer after last character
output;
NULL if no character has been output
or if it's conceptually before bufbeg. */
static uintmax_t totalnl; /* Total newline count before lastnl. */
-static off_t outleft; /* Maximum number of lines to be output. */
-static int pending; /* Pending lines of output.
+static intmax_t outleft; /* Maximum number of lines to be output. */
+static intmax_t pending; /* Pending lines of output.
Always kept 0 if out_quiet is true. */
static int done_on_match; /* Stop scanning file on first match. */
static int exit_on_match; /* Exit on first match. */
@@ -917,12 +922,12 @@ prpending (char const *lim)
/* Print the lines between BEG and LIM. Deal with context crap.
If NLINESP is non-null, store a count of lines between BEG and LIM. */
static void
-prtext (char const *beg, char const *lim, int *nlinesp)
+prtext (char const *beg, char const *lim, intmax_t *nlinesp)
{
static int used; /* avoid printing SEP_STR_GROUP before any output */
char const *bp, *p;
char eol = eolbyte;
- int i, n;
+ intmax_t i, n;
if (!out_quiet && pending > 0)
prpending (beg);
@@ -1026,10 +1031,10 @@ do_execute (char const *buf, size_t size, size_t
*match_size, char const *start_
/* Scan the specified portion of the buffer, matching lines (or
between matching lines if OUT_INVERT is true). Return a count of
lines printed. */
-static int
+static intmax_t
grepbuf (char const *beg, char const *lim)
{
- int nlines, n;
+ intmax_t nlines, n;
char const *p;
size_t match_offset;
size_t match_size;
@@ -1046,7 +1051,7 @@ grepbuf (char const *beg, char const *lim)
break;
if (!out_invert)
{
- prtext (b, endp, (int *) 0);
+ prtext (b, endp, NULL);
nlines++;
outleft--;
if (!outleft || done_on_match)
@@ -1079,10 +1084,10 @@ grepbuf (char const *beg, char const *lim)
/* Search a given file. Normally, return a count of lines printed;
but if the file is a directory and we search it recursively, then
return -2 if there was a match, and -1 otherwise. */
-static int
+static intmax_t
grep (int fd, char const *file, struct stats *stats)
{
- int nlines, i;
+ intmax_t nlines, i;
int not_text;
size_t residue, save;
char oldc;
@@ -1212,7 +1217,7 @@ static int
grepfile (char const *file, struct stats *stats)
{
int desc;
- int count;
+ intmax_t count;
int status;
filename = (file ? file : label ? label : _("(standard input)"));
@@ -1319,7 +1324,7 @@ grepfile (char const *file, struct stats *stats)
else
fputc (0, stdout);
}
- printf ("%d\n", count);
+ printf ("%" PRIdMAX "\n", count);
}
status = !count;
@@ -1590,12 +1595,12 @@ setmatcher (char const *m)
etc. to the option copies. Return the number N of options found.
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
etc. Backslash can be used to escape whitespace (and backslashes). */
-static int
+static size_t
prepend_args (char const *options, char *buf, char **argv)
{
char const *o = options;
char *b = buf;
- int n = 0;
+ size_t n = 0;
for (;;)
{
@@ -1625,10 +1630,14 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
if (options && *options)
{
char *buf = xmalloc (strlen (options) + 1);
- int prepended = prepend_args (options, buf, (char **) NULL);
+ size_t prepended = prepend_args (options, buf, NULL);
int argc = *pargc;
char *const *argv = *pargv;
- char **pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
+ char **pp;
+ enum { MAX_ARGS = MIN (INT_MAX, SIZE_MAX / sizeof *pp - 1) };
+ if (MAX_ARGS - argc < prepended)
+ xalloc_die ();
+ pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
*pargc = prepended + argc;
*pargv = pp;
*pp++ = *argv++;
@@ -1646,11 +1655,11 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
Process any digit options that were encountered on the way,
and store the resulting integer into *DEFAULT_CONTEXT. */
static int
-get_nondigit_option (int argc, char *const *argv, int *default_context)
+get_nondigit_option (int argc, char *const *argv, intmax_t *default_context)
{
static int prev_digit_optind = -1;
int opt, this_digit_optind, was_digit;
- char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
+ char buf[INT_BUFSIZE_BOUND (intmax_t) + 4];
char *p = buf;
was_digit = 0;
@@ -1760,11 +1769,11 @@ main (int argc, char **argv)
char *keys;
size_t keycc, oldcc, keyalloc;
int with_filenames;
- int opt, cc, status, prepended;
+ size_t cc;
+ int opt, status, prepended;
int prev_optind, last_recursive;
- int default_context;
+ intmax_t default_context;
FILE *fp;
-
exit_failure = EXIT_TROUBLE;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1776,7 +1785,7 @@ main (int argc, char **argv)
eolbyte = '\n';
filename_mask = ~0;
- max_count = TYPE_MAXIMUM (off_t);
+ max_count = INTMAX_MAX;
/* The value -1 means to use DEFAULT_CONTEXT. */
out_after = out_before = -1;
@@ -1947,23 +1956,15 @@ main (int argc, char **argv)
break;
case 'm':
- {
- uintmax_t value;
- switch (xstrtoumax (optarg, 0, 10, &value, ""))
- {
- case LONGINT_OK:
- max_count = value;
- if (0 <= max_count && max_count == value)
- break;
- /* Fall through. */
- case LONGINT_OVERFLOW:
- max_count = TYPE_MAXIMUM (off_t);
- break;
+ switch (xstrtoimax (optarg, 0, 10, &max_count, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ break;
- default:
- error (EXIT_TROUBLE, 0, _("invalid max count"));
- }
- }
+ default:
+ error (EXIT_TROUBLE, 0, _("invalid max count"));
+ }
break;
case 'n':
http://git.savannah.gnu.org/cgit/grep.git/commit/?id=a19dc139056aaf09137991bacef364c8fef60168
commit 8fcf61523644df42e1905c81bed26838e0b04f91
Author: Paul Eggert <address@hidden>
Date: Wed Feb 29 00:49:40 2012 -0800
grep: fix integer-overflow issues in main program
* NEWS: Document this.
* bootstrap.conf (gnulib_modules): Add inttypes, xstrtoimax.
Remove xstrtoumax.
* src/main.c: Include <inttypes.h>, for INTMAX_MAX, PRIdMAX.
(context_length_arg, prtext, grepbuf, grep, grepfile)
(get_nondigit_option, main):
Use intmax_t, not int, for line counts.
(context_length_arg, main): Silently ceiling line counts
to maximum value, since there's no practical difference between
doing that and using infinite-precision arithmetic.
(out_before, out_after, pending): Now intmax_t, not int.
(max_count, outleft): Now intmax_t, not off_t.
(prepend_args, prepend_default_options, main):
Use size_t, not int, for sizes.
(prepend_default_options): Check for int and size_t overflow.
diff --git a/NEWS b/NEWS
index 47e0ca4..5ff4027 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ GNU grep NEWS -*- outline
-*-
GNU C library's regular expression functions cannot handle such long lines.
[bug present since "the beginning"]
+ The -m, -A, -B, and -C options no longer mishandle context line
+ counts that do not fit in 'int'. Also, grep -c's counts are now
+ limited by the type 'intmax_t' (typically less than 2**63) rather
+ than 'int' (typically less than 2**31).
+
grep no longer silently suppresses errors when reading a directory
as if it were a text file. For example, "grep x ." now reports a
read error on most systems; formerly, it ignored the error.
diff --git a/bootstrap.conf b/bootstrap.conf
index 2b7a5ec..45bb33d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -41,6 +41,7 @@ gnupload
hard-locale
ignore-value
intprops
+inttypes
isatty
isblank
isdir
@@ -85,7 +86,7 @@ wcscoll
wctob
wctype-h
xalloc
-xstrtoumax
+xstrtoimax
'
gnulib_name=libgreputils
diff --git a/src/main.c b/src/main.c
index 3c5f6dd..7d83f4d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include "system.h"
@@ -425,17 +426,21 @@ clean_up_stdout (void)
close_stdout ();
}
-/* Convert STR to a positive integer, storing the result in *OUT.
+/* Convert STR to a nonnegative integer, storing the result in *OUT.
STR must be a valid context length argument; report an error if it
- isn't. */
+ isn't. Silently ceiling *OUT at the maximum value, as that is
+ practically equivalent to infinity for grep's purposes. */
static void
-context_length_arg (char const *str, int *out)
+context_length_arg (char const *str, intmax_t *out)
{
- uintmax_t value;
- if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK
- && 0 <= (*out = value)
- && *out == value))
+ switch (xstrtoimax (str, 0, 10, out, ""))
{
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ if (0 <= *out)
+ break;
+ /* Fall through. */
+ default:
error (EXIT_TROUBLE, 0, "%s: %s", str,
_("invalid context length argument"));
}
@@ -603,12 +608,12 @@ static int out_invert; /* Print nonmatching
stuff. */
static int out_file; /* Print filenames. */
static int out_line; /* Print line numbers. */
static int out_byte; /* Print byte offsets. */
-static int out_before; /* Lines of leading context. */
-static int out_after; /* Lines of trailing context. */
+static intmax_t out_before; /* Lines of leading context. */
+static intmax_t out_after; /* Lines of trailing context. */
static int count_matches; /* Count matching lines. */
static int list_files; /* List matching files. */
static int no_filenames; /* Suppress file names. */
-static off_t max_count; /* Stop after outputting this many
+static intmax_t max_count; /* Stop after outputting this many
lines from an input file. */
static int line_buffered; /* If nonzero, use line buffering, i.e.
fflush everyline out. */
@@ -622,8 +627,8 @@ static char const *lastout; /* Pointer after last character
output;
NULL if no character has been output
or if it's conceptually before bufbeg. */
static uintmax_t totalnl; /* Total newline count before lastnl. */
-static off_t outleft; /* Maximum number of lines to be output. */
-static int pending; /* Pending lines of output.
+static intmax_t outleft; /* Maximum number of lines to be output. */
+static intmax_t pending; /* Pending lines of output.
Always kept 0 if out_quiet is true. */
static int done_on_match; /* Stop scanning file on first match. */
static int exit_on_match; /* Exit on first match. */
@@ -917,12 +922,12 @@ prpending (char const *lim)
/* Print the lines between BEG and LIM. Deal with context crap.
If NLINESP is non-null, store a count of lines between BEG and LIM. */
static void
-prtext (char const *beg, char const *lim, int *nlinesp)
+prtext (char const *beg, char const *lim, intmax_t *nlinesp)
{
static int used; /* avoid printing SEP_STR_GROUP before any output */
char const *bp, *p;
char eol = eolbyte;
- int i, n;
+ intmax_t i, n;
if (!out_quiet && pending > 0)
prpending (beg);
@@ -1026,10 +1031,10 @@ do_execute (char const *buf, size_t size, size_t
*match_size, char const *start_
/* Scan the specified portion of the buffer, matching lines (or
between matching lines if OUT_INVERT is true). Return a count of
lines printed. */
-static int
+static intmax_t
grepbuf (char const *beg, char const *lim)
{
- int nlines, n;
+ intmax_t nlines, n;
char const *p;
size_t match_offset;
size_t match_size;
@@ -1046,7 +1051,7 @@ grepbuf (char const *beg, char const *lim)
break;
if (!out_invert)
{
- prtext (b, endp, (int *) 0);
+ prtext (b, endp, NULL);
nlines++;
outleft--;
if (!outleft || done_on_match)
@@ -1079,10 +1084,10 @@ grepbuf (char const *beg, char const *lim)
/* Search a given file. Normally, return a count of lines printed;
but if the file is a directory and we search it recursively, then
return -2 if there was a match, and -1 otherwise. */
-static int
+static intmax_t
grep (int fd, char const *file, struct stats *stats)
{
- int nlines, i;
+ intmax_t nlines, i;
int not_text;
size_t residue, save;
char oldc;
@@ -1212,7 +1217,7 @@ static int
grepfile (char const *file, struct stats *stats)
{
int desc;
- int count;
+ intmax_t count;
int status;
filename = (file ? file : label ? label : _("(standard input)"));
@@ -1319,7 +1324,7 @@ grepfile (char const *file, struct stats *stats)
else
fputc (0, stdout);
}
- printf ("%d\n", count);
+ printf ("%" PRIdMAX "\n", count);
}
status = !count;
@@ -1590,12 +1595,12 @@ setmatcher (char const *m)
etc. to the option copies. Return the number N of options found.
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
etc. Backslash can be used to escape whitespace (and backslashes). */
-static int
+static size_t
prepend_args (char const *options, char *buf, char **argv)
{
char const *o = options;
char *b = buf;
- int n = 0;
+ size_t n = 0;
for (;;)
{
@@ -1625,10 +1630,14 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
if (options && *options)
{
char *buf = xmalloc (strlen (options) + 1);
- int prepended = prepend_args (options, buf, (char **) NULL);
+ size_t prepended = prepend_args (options, buf, NULL);
int argc = *pargc;
char *const *argv = *pargv;
- char **pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
+ char **pp;
+ enum { MAX_ARGS = MIN (INT_MAX, SIZE_MAX / sizeof *pp - 1) };
+ if (MAX_ARGS - argc < prepended)
+ xalloc_die ();
+ pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
*pargc = prepended + argc;
*pargv = pp;
*pp++ = *argv++;
@@ -1646,11 +1655,11 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
Process any digit options that were encountered on the way,
and store the resulting integer into *DEFAULT_CONTEXT. */
static int
-get_nondigit_option (int argc, char *const *argv, int *default_context)
+get_nondigit_option (int argc, char *const *argv, intmax_t *default_context)
{
static int prev_digit_optind = -1;
int opt, this_digit_optind, was_digit;
- char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
+ char buf[INT_BUFSIZE_BOUND (intmax_t) + 4];
char *p = buf;
was_digit = 0;
@@ -1760,11 +1769,11 @@ main (int argc, char **argv)
char *keys;
size_t keycc, oldcc, keyalloc;
int with_filenames;
- int opt, cc, status, prepended;
+ size_t cc;
+ int opt, status, prepended;
int prev_optind, last_recursive;
- int default_context;
+ intmax_t default_context;
FILE *fp;
-
exit_failure = EXIT_TROUBLE;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1776,7 +1785,7 @@ main (int argc, char **argv)
eolbyte = '\n';
filename_mask = ~0;
- max_count = TYPE_MAXIMUM (off_t);
+ max_count = INTMAX_MAX;
/* The value -1 means to use DEFAULT_CONTEXT. */
out_after = out_before = -1;
@@ -1947,23 +1956,15 @@ main (int argc, char **argv)
break;
case 'm':
- {
- uintmax_t value;
- switch (xstrtoumax (optarg, 0, 10, &value, ""))
- {
- case LONGINT_OK:
- max_count = value;
- if (0 <= max_count && max_count == value)
- break;
- /* Fall through. */
- case LONGINT_OVERFLOW:
- max_count = TYPE_MAXIMUM (off_t);
- break;
+ switch (xstrtoimax (optarg, 0, 10, &max_count, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ break;
- default:
- error (EXIT_TROUBLE, 0, _("invalid max count"));
- }
- }
+ default:
+ error (EXIT_TROUBLE, 0, _("invalid max count"));
+ }
break;
case 'n':
http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cbbc1a45b9f843c811905c97c90a5d31f8e6c189
commit 8fcf61523644df42e1905c81bed26838e0b04f91
Author: Paul Eggert <address@hidden>
Date: Wed Feb 29 00:49:40 2012 -0800
grep: fix integer-overflow issues in main program
* NEWS: Document this.
* bootstrap.conf (gnulib_modules): Add inttypes, xstrtoimax.
Remove xstrtoumax.
* src/main.c: Include <inttypes.h>, for INTMAX_MAX, PRIdMAX.
(context_length_arg, prtext, grepbuf, grep, grepfile)
(get_nondigit_option, main):
Use intmax_t, not int, for line counts.
(context_length_arg, main): Silently ceiling line counts
to maximum value, since there's no practical difference between
doing that and using infinite-precision arithmetic.
(out_before, out_after, pending): Now intmax_t, not int.
(max_count, outleft): Now intmax_t, not off_t.
(prepend_args, prepend_default_options, main):
Use size_t, not int, for sizes.
(prepend_default_options): Check for int and size_t overflow.
diff --git a/NEWS b/NEWS
index 47e0ca4..5ff4027 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ GNU grep NEWS -*- outline
-*-
GNU C library's regular expression functions cannot handle such long lines.
[bug present since "the beginning"]
+ The -m, -A, -B, and -C options no longer mishandle context line
+ counts that do not fit in 'int'. Also, grep -c's counts are now
+ limited by the type 'intmax_t' (typically less than 2**63) rather
+ than 'int' (typically less than 2**31).
+
grep no longer silently suppresses errors when reading a directory
as if it were a text file. For example, "grep x ." now reports a
read error on most systems; formerly, it ignored the error.
diff --git a/bootstrap.conf b/bootstrap.conf
index 2b7a5ec..45bb33d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -41,6 +41,7 @@ gnupload
hard-locale
ignore-value
intprops
+inttypes
isatty
isblank
isdir
@@ -85,7 +86,7 @@ wcscoll
wctob
wctype-h
xalloc
-xstrtoumax
+xstrtoimax
'
gnulib_name=libgreputils
diff --git a/src/main.c b/src/main.c
index 3c5f6dd..7d83f4d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include "system.h"
@@ -425,17 +426,21 @@ clean_up_stdout (void)
close_stdout ();
}
-/* Convert STR to a positive integer, storing the result in *OUT.
+/* Convert STR to a nonnegative integer, storing the result in *OUT.
STR must be a valid context length argument; report an error if it
- isn't. */
+ isn't. Silently ceiling *OUT at the maximum value, as that is
+ practically equivalent to infinity for grep's purposes. */
static void
-context_length_arg (char const *str, int *out)
+context_length_arg (char const *str, intmax_t *out)
{
- uintmax_t value;
- if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK
- && 0 <= (*out = value)
- && *out == value))
+ switch (xstrtoimax (str, 0, 10, out, ""))
{
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ if (0 <= *out)
+ break;
+ /* Fall through. */
+ default:
error (EXIT_TROUBLE, 0, "%s: %s", str,
_("invalid context length argument"));
}
@@ -603,12 +608,12 @@ static int out_invert; /* Print nonmatching
stuff. */
static int out_file; /* Print filenames. */
static int out_line; /* Print line numbers. */
static int out_byte; /* Print byte offsets. */
-static int out_before; /* Lines of leading context. */
-static int out_after; /* Lines of trailing context. */
+static intmax_t out_before; /* Lines of leading context. */
+static intmax_t out_after; /* Lines of trailing context. */
static int count_matches; /* Count matching lines. */
static int list_files; /* List matching files. */
static int no_filenames; /* Suppress file names. */
-static off_t max_count; /* Stop after outputting this many
+static intmax_t max_count; /* Stop after outputting this many
lines from an input file. */
static int line_buffered; /* If nonzero, use line buffering, i.e.
fflush everyline out. */
@@ -622,8 +627,8 @@ static char const *lastout; /* Pointer after last character
output;
NULL if no character has been output
or if it's conceptually before bufbeg. */
static uintmax_t totalnl; /* Total newline count before lastnl. */
-static off_t outleft; /* Maximum number of lines to be output. */
-static int pending; /* Pending lines of output.
+static intmax_t outleft; /* Maximum number of lines to be output. */
+static intmax_t pending; /* Pending lines of output.
Always kept 0 if out_quiet is true. */
static int done_on_match; /* Stop scanning file on first match. */
static int exit_on_match; /* Exit on first match. */
@@ -917,12 +922,12 @@ prpending (char const *lim)
/* Print the lines between BEG and LIM. Deal with context crap.
If NLINESP is non-null, store a count of lines between BEG and LIM. */
static void
-prtext (char const *beg, char const *lim, int *nlinesp)
+prtext (char const *beg, char const *lim, intmax_t *nlinesp)
{
static int used; /* avoid printing SEP_STR_GROUP before any output */
char const *bp, *p;
char eol = eolbyte;
- int i, n;
+ intmax_t i, n;
if (!out_quiet && pending > 0)
prpending (beg);
@@ -1026,10 +1031,10 @@ do_execute (char const *buf, size_t size, size_t
*match_size, char const *start_
/* Scan the specified portion of the buffer, matching lines (or
between matching lines if OUT_INVERT is true). Return a count of
lines printed. */
-static int
+static intmax_t
grepbuf (char const *beg, char const *lim)
{
- int nlines, n;
+ intmax_t nlines, n;
char const *p;
size_t match_offset;
size_t match_size;
@@ -1046,7 +1051,7 @@ grepbuf (char const *beg, char const *lim)
break;
if (!out_invert)
{
- prtext (b, endp, (int *) 0);
+ prtext (b, endp, NULL);
nlines++;
outleft--;
if (!outleft || done_on_match)
@@ -1079,10 +1084,10 @@ grepbuf (char const *beg, char const *lim)
/* Search a given file. Normally, return a count of lines printed;
but if the file is a directory and we search it recursively, then
return -2 if there was a match, and -1 otherwise. */
-static int
+static intmax_t
grep (int fd, char const *file, struct stats *stats)
{
- int nlines, i;
+ intmax_t nlines, i;
int not_text;
size_t residue, save;
char oldc;
@@ -1212,7 +1217,7 @@ static int
grepfile (char const *file, struct stats *stats)
{
int desc;
- int count;
+ intmax_t count;
int status;
filename = (file ? file : label ? label : _("(standard input)"));
@@ -1319,7 +1324,7 @@ grepfile (char const *file, struct stats *stats)
else
fputc (0, stdout);
}
- printf ("%d\n", count);
+ printf ("%" PRIdMAX "\n", count);
}
status = !count;
@@ -1590,12 +1595,12 @@ setmatcher (char const *m)
etc. to the option copies. Return the number N of options found.
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
etc. Backslash can be used to escape whitespace (and backslashes). */
-static int
+static size_t
prepend_args (char const *options, char *buf, char **argv)
{
char const *o = options;
char *b = buf;
- int n = 0;
+ size_t n = 0;
for (;;)
{
@@ -1625,10 +1630,14 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
if (options && *options)
{
char *buf = xmalloc (strlen (options) + 1);
- int prepended = prepend_args (options, buf, (char **) NULL);
+ size_t prepended = prepend_args (options, buf, NULL);
int argc = *pargc;
char *const *argv = *pargv;
- char **pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
+ char **pp;
+ enum { MAX_ARGS = MIN (INT_MAX, SIZE_MAX / sizeof *pp - 1) };
+ if (MAX_ARGS - argc < prepended)
+ xalloc_die ();
+ pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
*pargc = prepended + argc;
*pargv = pp;
*pp++ = *argv++;
@@ -1646,11 +1655,11 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
Process any digit options that were encountered on the way,
and store the resulting integer into *DEFAULT_CONTEXT. */
static int
-get_nondigit_option (int argc, char *const *argv, int *default_context)
+get_nondigit_option (int argc, char *const *argv, intmax_t *default_context)
{
static int prev_digit_optind = -1;
int opt, this_digit_optind, was_digit;
- char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
+ char buf[INT_BUFSIZE_BOUND (intmax_t) + 4];
char *p = buf;
was_digit = 0;
@@ -1760,11 +1769,11 @@ main (int argc, char **argv)
char *keys;
size_t keycc, oldcc, keyalloc;
int with_filenames;
- int opt, cc, status, prepended;
+ size_t cc;
+ int opt, status, prepended;
int prev_optind, last_recursive;
- int default_context;
+ intmax_t default_context;
FILE *fp;
-
exit_failure = EXIT_TROUBLE;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1776,7 +1785,7 @@ main (int argc, char **argv)
eolbyte = '\n';
filename_mask = ~0;
- max_count = TYPE_MAXIMUM (off_t);
+ max_count = INTMAX_MAX;
/* The value -1 means to use DEFAULT_CONTEXT. */
out_after = out_before = -1;
@@ -1947,23 +1956,15 @@ main (int argc, char **argv)
break;
case 'm':
- {
- uintmax_t value;
- switch (xstrtoumax (optarg, 0, 10, &value, ""))
- {
- case LONGINT_OK:
- max_count = value;
- if (0 <= max_count && max_count == value)
- break;
- /* Fall through. */
- case LONGINT_OVERFLOW:
- max_count = TYPE_MAXIMUM (off_t);
- break;
+ switch (xstrtoimax (optarg, 0, 10, &max_count, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ break;
- default:
- error (EXIT_TROUBLE, 0, _("invalid max count"));
- }
- }
+ default:
+ error (EXIT_TROUBLE, 0, _("invalid max count"));
+ }
break;
case 'n':
http://git.savannah.gnu.org/cgit/grep.git/commit/?id=235aad711285fc6978f6ff26397743930b23f79a
commit 8fcf61523644df42e1905c81bed26838e0b04f91
Author: Paul Eggert <address@hidden>
Date: Wed Feb 29 00:49:40 2012 -0800
grep: fix integer-overflow issues in main program
* NEWS: Document this.
* bootstrap.conf (gnulib_modules): Add inttypes, xstrtoimax.
Remove xstrtoumax.
* src/main.c: Include <inttypes.h>, for INTMAX_MAX, PRIdMAX.
(context_length_arg, prtext, grepbuf, grep, grepfile)
(get_nondigit_option, main):
Use intmax_t, not int, for line counts.
(context_length_arg, main): Silently ceiling line counts
to maximum value, since there's no practical difference between
doing that and using infinite-precision arithmetic.
(out_before, out_after, pending): Now intmax_t, not int.
(max_count, outleft): Now intmax_t, not off_t.
(prepend_args, prepend_default_options, main):
Use size_t, not int, for sizes.
(prepend_default_options): Check for int and size_t overflow.
diff --git a/NEWS b/NEWS
index 47e0ca4..5ff4027 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ GNU grep NEWS -*- outline
-*-
GNU C library's regular expression functions cannot handle such long lines.
[bug present since "the beginning"]
+ The -m, -A, -B, and -C options no longer mishandle context line
+ counts that do not fit in 'int'. Also, grep -c's counts are now
+ limited by the type 'intmax_t' (typically less than 2**63) rather
+ than 'int' (typically less than 2**31).
+
grep no longer silently suppresses errors when reading a directory
as if it were a text file. For example, "grep x ." now reports a
read error on most systems; formerly, it ignored the error.
diff --git a/bootstrap.conf b/bootstrap.conf
index 2b7a5ec..45bb33d 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -41,6 +41,7 @@ gnupload
hard-locale
ignore-value
intprops
+inttypes
isatty
isblank
isdir
@@ -85,7 +86,7 @@ wcscoll
wctob
wctype-h
xalloc
-xstrtoumax
+xstrtoimax
'
gnulib_name=libgreputils
diff --git a/src/main.c b/src/main.c
index 3c5f6dd..7d83f4d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,6 +25,7 @@
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <stdio.h>
#include "system.h"
@@ -425,17 +426,21 @@ clean_up_stdout (void)
close_stdout ();
}
-/* Convert STR to a positive integer, storing the result in *OUT.
+/* Convert STR to a nonnegative integer, storing the result in *OUT.
STR must be a valid context length argument; report an error if it
- isn't. */
+ isn't. Silently ceiling *OUT at the maximum value, as that is
+ practically equivalent to infinity for grep's purposes. */
static void
-context_length_arg (char const *str, int *out)
+context_length_arg (char const *str, intmax_t *out)
{
- uintmax_t value;
- if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK
- && 0 <= (*out = value)
- && *out == value))
+ switch (xstrtoimax (str, 0, 10, out, ""))
{
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ if (0 <= *out)
+ break;
+ /* Fall through. */
+ default:
error (EXIT_TROUBLE, 0, "%s: %s", str,
_("invalid context length argument"));
}
@@ -603,12 +608,12 @@ static int out_invert; /* Print nonmatching
stuff. */
static int out_file; /* Print filenames. */
static int out_line; /* Print line numbers. */
static int out_byte; /* Print byte offsets. */
-static int out_before; /* Lines of leading context. */
-static int out_after; /* Lines of trailing context. */
+static intmax_t out_before; /* Lines of leading context. */
+static intmax_t out_after; /* Lines of trailing context. */
static int count_matches; /* Count matching lines. */
static int list_files; /* List matching files. */
static int no_filenames; /* Suppress file names. */
-static off_t max_count; /* Stop after outputting this many
+static intmax_t max_count; /* Stop after outputting this many
lines from an input file. */
static int line_buffered; /* If nonzero, use line buffering, i.e.
fflush everyline out. */
@@ -622,8 +627,8 @@ static char const *lastout; /* Pointer after last character
output;
NULL if no character has been output
or if it's conceptually before bufbeg. */
static uintmax_t totalnl; /* Total newline count before lastnl. */
-static off_t outleft; /* Maximum number of lines to be output. */
-static int pending; /* Pending lines of output.
+static intmax_t outleft; /* Maximum number of lines to be output. */
+static intmax_t pending; /* Pending lines of output.
Always kept 0 if out_quiet is true. */
static int done_on_match; /* Stop scanning file on first match. */
static int exit_on_match; /* Exit on first match. */
@@ -917,12 +922,12 @@ prpending (char const *lim)
/* Print the lines between BEG and LIM. Deal with context crap.
If NLINESP is non-null, store a count of lines between BEG and LIM. */
static void
-prtext (char const *beg, char const *lim, int *nlinesp)
+prtext (char const *beg, char const *lim, intmax_t *nlinesp)
{
static int used; /* avoid printing SEP_STR_GROUP before any output */
char const *bp, *p;
char eol = eolbyte;
- int i, n;
+ intmax_t i, n;
if (!out_quiet && pending > 0)
prpending (beg);
@@ -1026,10 +1031,10 @@ do_execute (char const *buf, size_t size, size_t
*match_size, char const *start_
/* Scan the specified portion of the buffer, matching lines (or
between matching lines if OUT_INVERT is true). Return a count of
lines printed. */
-static int
+static intmax_t
grepbuf (char const *beg, char const *lim)
{
- int nlines, n;
+ intmax_t nlines, n;
char const *p;
size_t match_offset;
size_t match_size;
@@ -1046,7 +1051,7 @@ grepbuf (char const *beg, char const *lim)
break;
if (!out_invert)
{
- prtext (b, endp, (int *) 0);
+ prtext (b, endp, NULL);
nlines++;
outleft--;
if (!outleft || done_on_match)
@@ -1079,10 +1084,10 @@ grepbuf (char const *beg, char const *lim)
/* Search a given file. Normally, return a count of lines printed;
but if the file is a directory and we search it recursively, then
return -2 if there was a match, and -1 otherwise. */
-static int
+static intmax_t
grep (int fd, char const *file, struct stats *stats)
{
- int nlines, i;
+ intmax_t nlines, i;
int not_text;
size_t residue, save;
char oldc;
@@ -1212,7 +1217,7 @@ static int
grepfile (char const *file, struct stats *stats)
{
int desc;
- int count;
+ intmax_t count;
int status;
filename = (file ? file : label ? label : _("(standard input)"));
@@ -1319,7 +1324,7 @@ grepfile (char const *file, struct stats *stats)
else
fputc (0, stdout);
}
- printf ("%d\n", count);
+ printf ("%" PRIdMAX "\n", count);
}
status = !count;
@@ -1590,12 +1595,12 @@ setmatcher (char const *m)
etc. to the option copies. Return the number N of options found.
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
etc. Backslash can be used to escape whitespace (and backslashes). */
-static int
+static size_t
prepend_args (char const *options, char *buf, char **argv)
{
char const *o = options;
char *b = buf;
- int n = 0;
+ size_t n = 0;
for (;;)
{
@@ -1625,10 +1630,14 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
if (options && *options)
{
char *buf = xmalloc (strlen (options) + 1);
- int prepended = prepend_args (options, buf, (char **) NULL);
+ size_t prepended = prepend_args (options, buf, NULL);
int argc = *pargc;
char *const *argv = *pargv;
- char **pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
+ char **pp;
+ enum { MAX_ARGS = MIN (INT_MAX, SIZE_MAX / sizeof *pp - 1) };
+ if (MAX_ARGS - argc < prepended)
+ xalloc_die ();
+ pp = xmalloc ((prepended + argc + 1) * sizeof *pp);
*pargc = prepended + argc;
*pargv = pp;
*pp++ = *argv++;
@@ -1646,11 +1655,11 @@ prepend_default_options (char const *options, int
*pargc, char ***pargv)
Process any digit options that were encountered on the way,
and store the resulting integer into *DEFAULT_CONTEXT. */
static int
-get_nondigit_option (int argc, char *const *argv, int *default_context)
+get_nondigit_option (int argc, char *const *argv, intmax_t *default_context)
{
static int prev_digit_optind = -1;
int opt, this_digit_optind, was_digit;
- char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
+ char buf[INT_BUFSIZE_BOUND (intmax_t) + 4];
char *p = buf;
was_digit = 0;
@@ -1760,11 +1769,11 @@ main (int argc, char **argv)
char *keys;
size_t keycc, oldcc, keyalloc;
int with_filenames;
- int opt, cc, status, prepended;
+ size_t cc;
+ int opt, status, prepended;
int prev_optind, last_recursive;
- int default_context;
+ intmax_t default_context;
FILE *fp;
-
exit_failure = EXIT_TROUBLE;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1776,7 +1785,7 @@ main (int argc, char **argv)
eolbyte = '\n';
filename_mask = ~0;
- max_count = TYPE_MAXIMUM (off_t);
+ max_count = INTMAX_MAX;
/* The value -1 means to use DEFAULT_CONTEXT. */
out_after = out_before = -1;
@@ -1947,23 +1956,15 @@ main (int argc, char **argv)
break;
case 'm':
- {
- uintmax_t value;
- switch (xstrtoumax (optarg, 0, 10, &value, ""))
- {
- case LONGINT_OK:
- max_count = value;
- if (0 <= max_count && max_count == value)
- break;
- /* Fall through. */
- case LONGINT_OVERFLOW:
- max_count = TYPE_MAXIMUM (off_t);
- break;
+ switch (xstrtoimax (optarg, 0, 10, &max_count, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_OVERFLOW:
+ break;
- default:
- error (EXIT_TROUBLE, 0, _("invalid max count"));
- }
- }
+ default:
+ error (EXIT_TROUBLE, 0, _("invalid max count"));
+ }
break;
case 'n':
-----------------------------------------------------------------------
Summary of changes:
HACKING | 6 +
Makefile.am | 5 +
NEWS | 12 +++
bootstrap.conf | 3 +-
src/dfa.c | 270 +++++++++++++++++++++++++++++-----------------------
src/dfa.h | 4 +-
src/dfasearch.c | 31 +++++--
src/kwset.c | 4 +-
src/kwset.h | 2 +-
src/main.c | 133 ++++++++++-----------------
src/pcresearch.c | 3 +
tests/Makefile.am | 1 +
tests/big-match | 32 ++++++
tests/init.cfg | 17 ++++
14 files changed, 306 insertions(+), 217 deletions(-)
create mode 100755 tests/big-match
hooks/post-receive
--
grep
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- grep branch, master, updated. v2.10-85-g8fcf615,
Paul Eggert <=