summaryrefslogtreecommitdiffstats
path: root/text-utils/more.c
diff options
context:
space:
mode:
authorKarel Zak2009-11-16 15:52:45 +0100
committerKarel Zak2009-11-16 15:52:45 +0100
commit1ac300932deab8dea2c43050921bbbdb36d62ff1 (patch)
tree0aebcaa8fd6804df7b030f4e938072cee62f4050 /text-utils/more.c
parenttests: add NTFS blkid test (diff)
downloadkernel-qcow2-util-linux-1ac300932deab8dea2c43050921bbbdb36d62ff1.tar.gz
kernel-qcow2-util-linux-1ac300932deab8dea2c43050921bbbdb36d62ff1.tar.xz
kernel-qcow2-util-linux-1ac300932deab8dea2c43050921bbbdb36d62ff1.zip
more: limited line buffer length results in corrupted UTF-8 text
Addresses-Debian-Bug: #552608 Reported-By: Roger Leigh <rleigh@debian.org> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'text-utils/more.c')
-rw-r--r--text-utils/more.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/text-utils/more.c b/text-utils/more.c
index 45a58e271..a152463c0 100644
--- a/text-utils/more.c
+++ b/text-utils/more.c
@@ -105,9 +105,10 @@ int get_line(register FILE *f, int *length);
void prbuf (register char *s, register int n);
void execute (char *filename, char *cmd, ...);
FILE *checkf (char *, int *);
+int prepare_line_buffer(void);
#define TBUFSIZ 1024
-#define LINSIZ 256
+#define LINSIZ 256 /* minimal Line buffer size */
#define ctrl(letter) (letter & 077)
#define RUBOUT '\177'
#define ESC '\033'
@@ -141,7 +142,8 @@ int nfiles; /* Number of files left to process */
char *shell; /* The name of the shell to use */
int shellp; /* A previous shell command exists */
sigjmp_buf restore;
-char Line[LINSIZ+2]; /* Line buffer */
+char *Line; /* Line buffer */
+size_t LineLen; /* size of Line buffer */
int Lpp = 24; /* lines per page */
char *Clear; /* clear screen */
char *eraseln; /* erase line */
@@ -284,6 +286,10 @@ int main(int argc, char **argv) {
fnames = argv;
setlocale(LC_ALL, "");
initterm ();
+ if (prepare_line_buffer()) {
+ fprintf(stderr, _("failed to initialize line buffer\n"));
+ exit(1);
+ }
nscroll = Lpp/2 - 1;
if (nscroll <= 0)
nscroll = 1;
@@ -767,6 +773,32 @@ static void prompt (char *filename)
inwait++;
}
+int prepare_line_buffer(void)
+{
+ char *nline;
+ size_t nsz = Mcol * 4;
+
+ if (LineLen >= nsz)
+ return 0;
+
+ if (nsz < LINSIZ)
+ nsz = LINSIZ;
+
+ nline = realloc(Line, nsz);
+ if (nline) {
+ Line = nline;
+ LineLen = nsz;
+ return 0;
+ }
+
+ /* error() uses siglongjmp(), we want to return from this
+ * function when the Line buffer is initilized first time in main()
+ */
+ if (Line)
+ error(_("out if memory"));
+ return -1;
+}
+
/*
* Get a logical line
*/
@@ -793,6 +825,8 @@ int get_line(register FILE *f, int *length)
memset (&state, '\0', sizeof (mbstate_t));
#endif
+ prepare_line_buffer();
+
p = Line;
column = 0;
c = Getc (f);
@@ -800,7 +834,7 @@ int get_line(register FILE *f, int *length)
Currline++;
c = Getc (f);
}
- while (p < &Line[LINSIZ - 1]) {
+ while (p < &Line[LineLen - 1]) {
#ifdef HAVE_WIDECHAR
if (fold_opt && use_mbc_buffer_flag && MB_CUR_MAX > 1) {
use_mbc_buffer_flag = 0;
@@ -871,11 +905,11 @@ process_mbc:
#if 0
if (c == '\033') { /* ESC */
c = Getc(f);
- while (c > ' ' && c < '0' && p < &Line[LINSIZ - 1]) {
+ while (c > ' ' && c < '0' && p < &Line[LineLen - 1]) {
*p++ = c;
c = Getc(f);
}
- if (c >= '0' && c < '\177' && p < &Line[LINSIZ - 1]) {
+ if (c >= '0' && c < '\177' && p < &Line[LineLen - 1]) {
*p++ = c;
c = Getc(f);
continue;
@@ -890,7 +924,7 @@ process_mbc:
promptlen = 0;
}
else {
- for (--p; p < &Line[LINSIZ - 1];) {
+ for (--p; p < &Line[LineLen - 1];) {
*p++ = ' ';
if ((++column & 7) == 0)
break;
@@ -2087,8 +2121,10 @@ void rdline (register FILE *f)
register int c;
register char *p;
+ prepare_line_buffer();
+
p = Line;
- while ((c = Getc (f)) != '\n' && c != EOF && p - Line < LINSIZ - 1)
+ while ((c = Getc (f)) != '\n' && c != EOF && p - Line < LineLen - 1)
*p++ = c;
if (c == '\n')
Currline++;