projects
/
pspp
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix up potential overflows in size calculations by replacing
[pspp]
/
src
/
ascii.c
diff --git
a/src/ascii.c
b/src/ascii.c
index bdaac410566cdf55a5ef26e7bb0e4a319ac6db31..bd55d0efee9b94905dde4dec4715d7c8065f07c5 100644
(file)
--- a/
src/ascii.c
+++ b/
src/ascii.c
@@
-14,8
+14,8
@@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 5
9 Temple Place - Suite 330
, Boston, MA
- 0211
1-1307
, USA. */
+ Foundation, Inc., 5
1 Franklin Street, Fifth Floor
, Boston, MA
+ 0211
0-1301
, USA. */
#include <config.h>
#include "error.h"
#include <config.h>
#include "error.h"
@@
-32,6
+32,9
@@
#include "pool.h"
#include "version.h"
#include "pool.h"
#include "version.h"
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
/* ASCII driver options: (defaults listed first)
output-file="pspp.list"
/* ASCII driver options: (defaults listed first)
output-file="pspp.list"
@@
-165,9
+168,9
@@
struct ascii_driver_ext
int bottom_margin; /* Bottom margin in lines. */
int paginate; /* 1=insert formfeeds. */
int tab_width; /* Width of a tab; 0 not to use tabs. */
int bottom_margin; /* Bottom margin in lines. */
int paginate; /* 1=insert formfeeds. */
int tab_width; /* Width of a tab; 0 not to use tabs. */
- struct
len
_string ops[OPS_COUNT]; /* Basic output strings. */
- struct
len
_string box[LNS_COUNT]; /* Line & box drawing characters. */
- struct
len
_string fonts[FSTY_COUNT]; /* Font styles; NULL=overstrike. */
+ struct
fixed
_string ops[OPS_COUNT]; /* Basic output strings. */
+ struct
fixed
_string box[LNS_COUNT]; /* Line & box drawing characters. */
+ struct
fixed
_string fonts[FSTY_COUNT]; /* Font styles; NULL=overstrike. */
int overstrike_style; /* OVS_SINGLE or OVS_LINE. */
int carriage_return_style; /* Carriage return style. */
int squeeze_blank_lines; /* 1=squeeze multiple blank lines into one. */
int overstrike_style; /* OVS_SINGLE or OVS_LINE. */
int carriage_return_style; /* Carriage return style. */
int squeeze_blank_lines; /* 1=squeeze multiple blank lines into one. */
@@
-184,22
+187,29
@@
struct ascii_driver_ext
#endif
};
#endif
};
-static struct pool *ascii_pool;
-
static int postopen (struct file_ext *);
static int preclose (struct file_ext *);
static int postopen (struct file_ext *);
static int preclose (struct file_ext *);
+static struct outp_option_info *option_info;
+
static int
ascii_open_global (struct outp_class *this UNUSED)
{
static int
ascii_open_global (struct outp_class *this UNUSED)
{
- ascii_pool = pool_create ();
+ option_info = xmalloc (sizeof *option_info);
+ option_info->initial = 0;
+ option_info->options = 0;
return 1;
}
return 1;
}
+
+static char *s;
static int
ascii_close_global (struct outp_class *this UNUSED)
{
static int
ascii_close_global (struct outp_class *this UNUSED)
{
- pool_destroy (ascii_pool);
+ free(option_info->initial);
+ free(option_info->options);
+ free(option_info);
+ free(s);
return 1;
}
return 1;
}
@@
-221,7
+231,7
@@
ascii_preopen_driver (struct outp_driver *this)
assert (this->driver_open == 0);
msg (VM (1), _("ASCII driver initializing as `%s'..."), this->name);
assert (this->driver_open == 0);
msg (VM (1), _("ASCII driver initializing as `%s'..."), this->name);
- this->ext = x = xmalloc (sizeof
(struct ascii_driver_ext)
);
+ this->ext = x = xmalloc (sizeof
*x
);
x->char_set = CHS_ASCII;
x->headers = 1;
x->page_length = 66;
x->char_set = CHS_ASCII;
x->headers = 1;
x->page_length = 66;
@@
-288,11
+298,11
@@
ascii_postopen_driver (struct outp_driver *this)
this->length = x->l * this->vert;
if (ls_null_p (&x->ops[OPS_FORMFEED]))
this->length = x->l * this->vert;
if (ls_null_p (&x->ops[OPS_FORMFEED]))
- ls_create (
ascii_pool,
&x->ops[OPS_FORMFEED], "\f");
+ ls_create (&x->ops[OPS_FORMFEED], "\f");
if (ls_null_p (&x->ops[OPS_NEWLINE])
if (ls_null_p (&x->ops[OPS_NEWLINE])
- || !strcmp (ls_
value
(&x->ops[OPS_NEWLINE]), "default"))
+ || !strcmp (ls_
c_str
(&x->ops[OPS_NEWLINE]), "default"))
{
{
- ls_create (
ascii_pool,
&x->ops[OPS_NEWLINE], "\n");
+ ls_create (&x->ops[OPS_NEWLINE], "\n");
x->file.mode = "wt";
}
x->file.mode = "wt";
}
@@
-351,7
+361,7
@@
ascii_postopen_driver (struct outp_driver *this)
c[0] = '+';
break;
}
c[0] = '+';
break;
}
- ls_create (
ascii_pool,
&x->box[i], c);
+ ls_create (&x->box[i], c);
}
}
}
}
@@
-389,11
+399,18
@@
static int
ascii_close_driver (struct outp_driver *this)
{
struct ascii_driver_ext *x = this->ext;
ascii_close_driver (struct outp_driver *this)
{
struct ascii_driver_ext *x = this->ext;
+ int i;
assert (this->driver_open == 1);
msg (VM (2), _("%s: Beginning closing..."), this->name);
x = this->ext;
assert (this->driver_open == 1);
msg (VM (2), _("%s: Beginning closing..."), this->name);
x = this->ext;
+ for (i = 0; i < OPS_COUNT; i++)
+ ls_destroy (&x->ops[i]);
+ for (i = 0; i < LNS_COUNT; i++)
+ ls_destroy (&x->box[i]);
+ for (i = 0; i < FSTY_COUNT; i++)
+ ls_destroy (&x->fonts[i]);
if (x->lines != NULL)
{
int line;
if (x->lines != NULL)
{
int line;
@@
-452,7
+469,6
@@
static struct outp_option option_tab[] =
{"squeeze", boolean_arg, 2},
{"", 0, 0},
};
{"squeeze", boolean_arg, 2},
{"", 0, 0},
};
-static struct outp_option_info option_info;
static void
ascii_option (struct outp_driver *this, const char *key,
static void
ascii_option (struct outp_driver *this, const char *key,
@@
-462,7
+478,7
@@
ascii_option (struct outp_driver *this, const char *key,
int cat, subcat;
const char *value;
int cat, subcat;
const char *value;
- value = ds_
value
(val);
+ value = ds_
c_str
(val);
if (!strncmp (key, "box[", 4))
{
char *tail;
if (!strncmp (key, "box[", 4))
{
char *tail;
@@
-476,11
+492,11
@@
ascii_option (struct outp_driver *this, const char *key,
}
if (!ls_null_p (&x->box[indx]))
msg (SW, _("Duplicate value for key `%s'."), key);
}
if (!ls_null_p (&x->box[indx]))
msg (SW, _("Duplicate value for key `%s'."), key);
- ls_create (
ascii_pool,
&x->box[indx], value);
+ ls_create (&x->box[indx], value);
return;
}
return;
}
- cat = outp_match_keyword (key, option_tab,
&
option_info, &subcat);
+ cat = outp_match_keyword (key, option_tab, option_info, &subcat);
switch (cat)
{
case 0:
switch (cat)
{
case 0:
@@
-586,7
+602,7
@@
ascii_option (struct outp_driver *this, const char *key,
break;
case string_arg:
{
break;
case string_arg:
{
- struct
len
_string *s;
+ struct
fixed
_string *s;
switch (subcat)
{
case 0:
switch (subcat)
{
case 0:
@@
-605,17
+621,17
@@
ascii_option (struct outp_driver *this, const char *key,
assert (0);
abort ();
}
assert (0);
abort ();
}
- ls_create (
ascii_pool,
s, value);
+ ls_create (s, value);
}
break;
case font_string_arg:
{
if (!strcmp (value, "overstrike"))
{
}
break;
case font_string_arg:
{
if (!strcmp (value, "overstrike"))
{
- ls_destroy (
ascii_pool,
&x->fonts[subcat]);
+ ls_destroy (&x->fonts[subcat]);
return;
}
return;
}
- ls_create (
ascii_pool,
&x->fonts[subcat], value);
+ ls_create (&x->fonts[subcat], value);
}
break;
case boolean_arg:
}
break;
case boolean_arg:
@@
-657,9
+673,9
@@
int
postopen (struct file_ext *f)
{
struct ascii_driver_ext *x = f->param;
postopen (struct file_ext *f)
{
struct ascii_driver_ext *x = f->param;
- struct
len
_string *s = &x->ops[OPS_INIT];
+ struct
fixed
_string *s = &x->ops[OPS_INIT];
- if (!ls_empty_p (s) && fwrite (ls_
value
(s), ls_length (s), 1, f->file) < 1)
+ if (!ls_empty_p (s) && fwrite (ls_
c_str
(s), ls_length (s), 1, f->file) < 1)
{
msg (ME, _("ASCII output driver: %s: %s"),
f->filename, strerror (errno));
{
msg (ME, _("ASCII output driver: %s: %s"),
f->filename, strerror (errno));
@@
-672,9
+688,9
@@
int
preclose (struct file_ext *f)
{
struct ascii_driver_ext *x = f->param;
preclose (struct file_ext *f)
{
struct ascii_driver_ext *x = f->param;
- struct
len
_string *d = &x->ops[OPS_DONE];
+ struct
fixed
_string *d = &x->ops[OPS_DONE];
- if (!ls_empty_p (d) && fwrite (ls_
value
(d), ls_length (d), 1, f->file) < 1)
+ if (!ls_empty_p (d) && fwrite (ls_
c_str
(d), ls_length (d), 1, f->file) < 1)
{
msg (ME, _("ASCII output driver: %s: %s"),
f->filename, strerror (errno));
{
msg (ME, _("ASCII output driver: %s: %s"),
f->filename, strerror (errno));
@@
-700,7
+716,7
@@
ascii_open_page (struct outp_driver *this)
if (x->l > x->lines_cap)
{
if (x->l > x->lines_cap)
{
- x->lines = x
realloc (x->lines, sizeof *x->lines * x->l
);
+ x->lines = x
nrealloc (x->lines, x->l, sizeof *x->lines
);
for (i = x->lines_cap; i < x->l; i++)
{
struct line *line = &x->lines[i];
for (i = x->lines_cap; i < x->l; i++)
{
struct line *line = &x->lines[i];
@@
-730,8
+746,8
@@
expand_line (struct ascii_driver_ext *x, int i, int l)
if (l > line->char_cap)
{
line->char_cap = l * 2;
if (l > line->char_cap)
{
line->char_cap = l * 2;
- line->chars = xrealloc (line->chars,
-
line->char_cap *
sizeof *line->chars);
+ line->chars = x
n
realloc (line->chars,
+
line->char_cap,
sizeof *line->chars);
}
for (j = line->char_cnt; j < l; j++)
line->chars[j] = ' ';
}
for (j = line->char_cnt; j < l; j++)
line->chars[j] = ' ';
@@
-971,7
+987,7
@@
delineate (struct outp_driver *this, struct outp_text *t, int draw)
int max_y;
/* Current position in string, character following end of string. */
int max_y;
/* Current position in string, character following end of string. */
- const char *s = ls_
value
(&t->s);
+ const char *s = ls_
c_str
(&t->s);
const char *end = ls_end (&t->s);
/* Temporary struct outp_text to pass to low-level function. */
const char *end = ls_end (&t->s);
/* Temporary struct outp_text to pass to low-level function. */
@@
-1103,7
+1119,7
@@
text_draw (struct outp_driver *this, struct outp_text *t)
int x = t->x;
int y = t->y;
int x = t->x;
int y = t->y;
- char *s = ls_
value
(&t->s);
+ char *s = ls_
c_str
(&t->s);
/* Expand the line with the assumption that S takes up LEN character
spaces (sometimes it takes up less). */
/* Expand the line with the assumption that S takes up LEN character
spaces (sometimes it takes up less). */
@@
-1142,8
+1158,8
@@
text_draw (struct outp_driver *this, struct outp_text *t)
/* ascii_close_page () and support routines. */
#define LINE_BUF_SIZE 1024
/* ascii_close_page () and support routines. */
#define LINE_BUF_SIZE 1024
-static
unsigned
char *line_buf;
-static
unsigned
char *line_p;
+static char *line_buf;
+static char *line_p;
static inline int
commit_line_buf (struct outp_driver *this)
static inline int
commit_line_buf (struct outp_driver *this)
@@
-1196,12
+1212,12
@@
output_shorts (struct outp_driver *this,
{
if (*bp & 0x800)
{
{
if (*bp & 0x800)
{
- struct
len
_string *box = &ext->box[*bp & 0xff];
+ struct
fixed
_string *box = &ext->box[*bp & 0xff];
size_t len = ls_length (box);
if (remaining >= len)
{
size_t len = ls_length (box);
if (remaining >= len)
{
- memcpy (line_p, ls_
value
(box), len);
+ memcpy (line_p, ls_
c_str
(box), len);
line_p += len;
remaining -= len;
}
line_p += len;
remaining -= len;
}
@@
-1209,13
+1225,13
@@
output_shorts (struct outp_driver *this,
{
if (!commit_line_buf (this))
return 0;
{
if (!commit_line_buf (this))
return 0;
- output_string (this, ls_
value
(box), ls_end (box));
+ output_string (this, ls_
c_str
(box), ls_end (box));
remaining = LINE_BUF_SIZE - (line_p - line_buf);
}
}
else if (*bp & 0x0300)
{
remaining = LINE_BUF_SIZE - (line_p - line_buf);
}
}
else if (*bp & 0x0300)
{
- struct
len
_string *on;
+ struct
fixed
_string *on;
char buf[5];
int len;
char buf[5];
int len;
@@
-1296,7
+1312,7
@@
output_shorts (struct outp_driver *this,
/* Writes CH into line_buf N times, or to THIS->output if line_buf
overflows. */
static inline void
/* Writes CH into line_buf N times, or to THIS->output if line_buf
overflows. */
static inline void
-output_char (struct outp_driver *this, int n,
int
ch)
+output_char (struct outp_driver *this, int n,
char
ch)
{
if (LINE_BUF_SIZE - (line_p - line_buf) >= n)
{
{
if (LINE_BUF_SIZE - (line_p - line_buf) >= n)
{
@@
-1360,7
+1376,7
@@
output_lines (struct outp_driver *this, int first, int count)
struct ascii_driver_ext *ext = this->ext;
int line_num;
struct ascii_driver_ext *ext = this->ext;
int line_num;
- struct
len
_string *newline = &ext->ops[OPS_NEWLINE];
+ struct
fixed
_string *newline = &ext->ops[OPS_NEWLINE];
int n_chars;
int n_passes;
int n_chars;
int n_passes;
@@
-1408,7
+1424,7
@@
output_lines (struct outp_driver *this, int first, int count)
/* Turn off old font. */
if (attr != (OUTP_F_R << 8))
{
/* Turn off old font. */
if (attr != (OUTP_F_R << 8))
{
- struct
len
_string *off;
+ struct
fixed
_string *off;
switch (attr)
{
switch (attr)
{
@@
-1426,14
+1442,14
@@
output_lines (struct outp_driver *this, int first, int count)
abort ();
}
if (off)
abort ();
}
if (off)
- output_string (this, ls_
value
(off), ls_end (off));
+ output_string (this, ls_
c_str
(off), ls_end (off));
}
/* Turn on new font. */
attr = (*bp & 0x0300);
if (attr != (OUTP_F_R << 8))
{
}
/* Turn on new font. */
attr = (*bp & 0x0300);
if (attr != (OUTP_F_R << 8))
{
- struct
len
_string *on;
+ struct
fixed
_string *on;
switch (attr)
{
switch (attr)
{
@@
-1451,14
+1467,14
@@
output_lines (struct outp_driver *this, int first, int count)
abort ();
}
if (on)
abort ();
}
if (on)
- output_string (this, ls_
value
(on), ls_end (on));
+ output_string (this, ls_
c_str
(on), ls_end (on));
}
ep = bp + 1;
}
if (n_passes > 1)
{
}
ep = bp + 1;
}
if (n_passes > 1)
{
-
unsigned
char ch;
+ char ch;
return_carriage (this, n_chars);
n_chars = 0;
return_carriage (this, n_chars);
n_chars = 0;
@@
-1510,19
+1526,19
@@
output_lines (struct outp_driver *this, int first, int count)
}
}
}
}
- output_string (this, ls_
value
(newline), ls_end (newline));
+ output_string (this, ls_
c_str
(newline), ls_end (newline));
}
}
}
}
+
static int
ascii_close_page (struct outp_driver *this)
{
static int
ascii_close_page (struct outp_driver *this)
{
- static unsigned char *s;
static int s_len;
struct ascii_driver_ext *x = this->ext;
int nl_len, ff_len, total_len;
static int s_len;
struct ascii_driver_ext *x = this->ext;
int nl_len, ff_len, total_len;
-
unsigned
char *cp;
+ char *cp;
int i;
assert (this->driver_open && this->page_open);
int i;
assert (this->driver_open && this->page_open);
@@
-1542,7
+1558,7
@@
ascii_close_page (struct outp_driver *this)
}
for (cp = s, i = 0; i < x->top_margin; i++)
{
}
for (cp = s, i = 0; i < x->top_margin; i++)
{
- memcpy (cp, ls_
value
(&x->ops[OPS_NEWLINE]), nl_len);
+ memcpy (cp, ls_
c_str
(&x->ops[OPS_NEWLINE]), nl_len);
cp += nl_len;
}
output_string (this, s, &s[total_len]);
cp += nl_len;
}
output_string (this, s, &s[total_len]);
@@
-1572,7
+1588,7
@@
ascii_close_page (struct outp_driver *this)
len = min ((int) strlen (outp_title), x->w);
memcpy (s, outp_title, len);
}
len = min ((int) strlen (outp_title), x->w);
memcpy (s, outp_title, len);
}
- memcpy (&s[x->w], ls_
value
(&x->ops[OPS_NEWLINE]), nl_len);
+ memcpy (&s[x->w], ls_
c_str
(&x->ops[OPS_NEWLINE]), nl_len);
output_string (this, s, &s[total_len]);
memset (s, ' ', x->w);
output_string (this, s, &s[total_len]);
memset (s, ' ', x->w);
@@
-1585,7
+1601,7
@@
ascii_close_page (struct outp_driver *this)
len = min ((int) strlen (string), x->w);
memcpy (s, string, len);
}
len = min ((int) strlen (string), x->w);
memcpy (s, string, len);
}
- memcpy (&s[x->w], ls_
value
(&x->ops[OPS_NEWLINE]), nl_len);
+ memcpy (&s[x->w], ls_
c_str
(&x->ops[OPS_NEWLINE]), nl_len);
output_string (this, s, &s[total_len]);
output_string (this, &s[x->w], &s[total_len]);
}
output_string (this, s, &s[total_len]);
output_string (this, &s[x->w], &s[total_len]);
}
@@
-1600,12
+1616,13
@@
ascii_close_page (struct outp_driver *this)
s = xrealloc (s, total_len);
for (cp = s, i = 0; i < x->bottom_margin; i++)
{
s = xrealloc (s, total_len);
for (cp = s, i = 0; i < x->bottom_margin; i++)
{
- memcpy (cp, ls_
value
(&x->ops[OPS_NEWLINE]), nl_len);
+ memcpy (cp, ls_
c_str
(&x->ops[OPS_NEWLINE]), nl_len);
cp += nl_len;
}
cp += nl_len;
}
- memcpy (cp, ls_
value
(&x->ops[OPS_FORMFEED]), ff_len);
+ memcpy (cp, ls_
c_str
(&x->ops[OPS_FORMFEED]), ff_len);
if ( x->paginate )
output_string (this, s, &s[total_len]);
if ( x->paginate )
output_string (this, s, &s[total_len]);
+
if (line_p != line_buf && !commit_line_buf (this))
return 0;
if (line_p != line_buf && !commit_line_buf (this))
return 0;
@@
-1613,6
+1630,21
@@
ascii_close_page (struct outp_driver *this)
return 1;
}
return 1;
}
+
+
+static void
+ascii_chart_initialise(struct outp_driver *d UNUSED, struct chart *ch )
+{
+ msg(MW, _("Charts are unsupported with ascii drivers."));
+ ch->lp = 0;
+}
+
+static void
+ascii_chart_finalise(struct outp_driver *d UNUSED, struct chart *ch UNUSED)
+{
+
+}
+
struct outp_class ascii_class =
{
"ascii",
struct outp_class ascii_class =
{
"ascii",
@@
-1651,4
+1683,7
@@
struct outp_class ascii_class =
ascii_text_get_size,
ascii_text_metrics,
ascii_text_draw,
ascii_text_get_size,
ascii_text_metrics,
ascii_text_draw,
+
+ ascii_chart_initialise,
+ ascii_chart_finalise
};
};