Allow user to omit font size specification when loading a font. In addition
the following fixes had been made: - check the size of the font being loaded and compare it with possible sizes to minimise possibility of loading something that is not a fontfile at all and turning console screen into garbage; - prevent buffer overflow (and coredump as a result ) when loading valid uuencoded file with size that exceeds allocated buffer; - correct and improve several error messages. Approved by: -audit, -hackers (silently)
This commit is contained in:
parent
92d86b9e1e
commit
5e0db936b5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=75344
@ -35,10 +35,11 @@ static const char rcsid[] =
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
|
|
||||||
int decode(FILE *fd, char *buffer)
|
int decode(FILE *fd, char *buffer, int len)
|
||||||
{
|
{
|
||||||
int n, pos = 0;
|
int n, pos = 0, tpos;
|
||||||
char *p;
|
char *bp, *p;
|
||||||
|
char tbuffer[3];
|
||||||
char temp[128];
|
char temp[128];
|
||||||
|
|
||||||
#define DEC(c) (((c) - ' ') & 0x3f)
|
#define DEC(c) (((c) - ' ') & 0x3f)
|
||||||
@ -48,31 +49,49 @@ int decode(FILE *fd, char *buffer)
|
|||||||
return(0);
|
return(0);
|
||||||
} while (strncmp(temp, "begin ", 6));
|
} while (strncmp(temp, "begin ", 6));
|
||||||
sscanf(temp, "begin %o %s", &n, temp);
|
sscanf(temp, "begin %o %s", &n, temp);
|
||||||
|
bp = buffer;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!fgets(p = temp, sizeof(temp), fd))
|
if (!fgets(p = temp, sizeof(temp), fd))
|
||||||
return(0);
|
return(0);
|
||||||
if ((n = DEC(*p)) <= 0)
|
if ((n = DEC(*p)) <= 0)
|
||||||
break;
|
break;
|
||||||
for (++p; n > 0; p += 4, n -= 3)
|
for (++p; n > 0; p += 4, n -= 3) {
|
||||||
|
tpos = 0;
|
||||||
if (n >= 3) {
|
if (n >= 3) {
|
||||||
buffer[pos++] = DEC(p[0])<<2 | DEC(p[1])>>4;
|
tbuffer[tpos++] = DEC(p[0])<<2 | DEC(p[1])>>4;
|
||||||
buffer[pos++] = DEC(p[1])<<4 | DEC(p[2])>>2;
|
tbuffer[tpos++] = DEC(p[1])<<4 | DEC(p[2])>>2;
|
||||||
buffer[pos++] = DEC(p[2])<<6 | DEC(p[3]);
|
tbuffer[tpos++] = DEC(p[2])<<6 | DEC(p[3]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (n >= 1) {
|
if (n >= 1) {
|
||||||
buffer[pos++] =
|
tbuffer[tpos++] =
|
||||||
DEC(p[0])<<2 | DEC(p[1])>>4;
|
DEC(p[0])<<2 | DEC(p[1])>>4;
|
||||||
}
|
}
|
||||||
if (n >= 2) {
|
if (n >= 2) {
|
||||||
buffer[pos++] =
|
tbuffer[tpos++] =
|
||||||
DEC(p[1])<<4 | DEC(p[2])>>2;
|
DEC(p[1])<<4 | DEC(p[2])>>2;
|
||||||
}
|
}
|
||||||
if (n >= 3) {
|
if (n >= 3) {
|
||||||
buffer[pos++] =
|
tbuffer[tpos++] =
|
||||||
DEC(p[2])<<6 | DEC(p[3]);
|
DEC(p[2])<<6 | DEC(p[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tpos == 0)
|
||||||
|
continue;
|
||||||
|
if (tpos + pos > len) {
|
||||||
|
tpos = len - pos;
|
||||||
|
/*
|
||||||
|
* Arrange return value > len to indicate
|
||||||
|
* overflow.
|
||||||
|
*/
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
bcopy(tbuffer, bp, tpos);
|
||||||
|
pos += tpos;
|
||||||
|
bp += tpos;
|
||||||
|
if (pos > len)
|
||||||
|
return(pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!fgets(temp, sizeof(temp), fd) || strcmp(temp, "end\n"))
|
if (!fgets(temp, sizeof(temp), fd) || strcmp(temp, "end\n"))
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -1 +1,3 @@
|
|||||||
int decode(FILE *fd, char *buffer);
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
|
int decode(FILE *fd, char *buffer, int len);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
.Op Fl b Ar color
|
.Op Fl b Ar color
|
||||||
.Op Fl c Ar appearance
|
.Op Fl c Ar appearance
|
||||||
.Op Fl d
|
.Op Fl d
|
||||||
.Op Fl f Ar size Ar file
|
.Op Fl f Oo Ar size Oc Ar \ file
|
||||||
.Op Fl g Ar geometry
|
.Op Fl g Ar geometry
|
||||||
.Op Fl i Cm adapter | mode
|
.Op Fl i Cm adapter | mode
|
||||||
.Op Fl l Ar screen_map
|
.Op Fl l Ar screen_map
|
||||||
@ -142,7 +142,7 @@ or
|
|||||||
Used together with the
|
Used together with the
|
||||||
.Xr moused 8
|
.Xr moused 8
|
||||||
daemon for text mode cut & paste functionality.
|
daemon for text mode cut & paste functionality.
|
||||||
.It Fl f Ar size Ar file
|
.It Fl f [ Ar size ] Ar file
|
||||||
Load font
|
Load font
|
||||||
.Ar file
|
.Ar file
|
||||||
for
|
for
|
||||||
@ -157,6 +157,11 @@ You can also use the menu-driven
|
|||||||
.Xr vidfont 1
|
.Xr vidfont 1
|
||||||
command to load the font of your choice.
|
command to load the font of your choice.
|
||||||
.Pp
|
.Pp
|
||||||
|
.Ar Size
|
||||||
|
may be omitted, in this case
|
||||||
|
.Nm
|
||||||
|
will try to guess it from the size of font file.
|
||||||
|
.Pp
|
||||||
Note that older video cards, such as MDA and CGA, do not support
|
Note that older video cards, such as MDA and CGA, do not support
|
||||||
software font.
|
software font.
|
||||||
See also
|
See also
|
||||||
@ -296,6 +301,11 @@ you may abbreviate the file name as
|
|||||||
.Pp
|
.Pp
|
||||||
.Dl vidcontrol -f 8x16 iso-8x16
|
.Dl vidcontrol -f 8x16 iso-8x16
|
||||||
.Pp
|
.Pp
|
||||||
|
Furthermore, you can also omit font size
|
||||||
|
.Dq 8x16 :
|
||||||
|
.Pp
|
||||||
|
.Dl vidcontrol -f iso-8x16
|
||||||
|
.Pp
|
||||||
Likewise, you can also abbreviate the screen output map file name for
|
Likewise, you can also abbreviate the screen output map file name for
|
||||||
the
|
the
|
||||||
.Fl l
|
.Fl l
|
||||||
|
@ -41,6 +41,8 @@ static const char rcsid[] =
|
|||||||
#include <sys/fbio.h>
|
#include <sys/fbio.h>
|
||||||
#include <sys/consio.h>
|
#include <sys/consio.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
|
|
||||||
@ -74,12 +76,13 @@ usage()
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
nextarg(int ac, char **av, int *indp, int oc)
|
nextarg(int ac, char **av, int *indp, int oc, int strict)
|
||||||
{
|
{
|
||||||
if (*indp < ac)
|
if (*indp < ac)
|
||||||
return(av[(*indp)++]);
|
return(av[(*indp)++]);
|
||||||
errx(1, "option requires two arguments -- %c", oc);
|
if (strict != 0)
|
||||||
return("");
|
errx(1, "option requires two arguments -- %c", oc);
|
||||||
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -129,7 +132,7 @@ load_scrnmap(char *filename)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size = sizeof(scrnmap);
|
size = sizeof(scrnmap);
|
||||||
if (decode(fd, (char *)&scrnmap) != size) {
|
if (decode(fd, (char *)&scrnmap, size) != size) {
|
||||||
rewind(fd);
|
rewind(fd);
|
||||||
if (fread(&scrnmap, 1, size, fd) != size) {
|
if (fread(&scrnmap, 1, size, fd) != size) {
|
||||||
warnx("bad screenmap file");
|
warnx("bad screenmap file");
|
||||||
@ -176,16 +179,38 @@ print_scrnmap()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fsize(FILE *file)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
if (fstat(fileno(file), &sb) == 0)
|
||||||
|
return sb.st_size;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DATASIZE(x) ((x).w * (x).h * 256 / 8)
|
||||||
|
|
||||||
void
|
void
|
||||||
load_font(char *type, char *filename)
|
load_font(char *type, char *filename)
|
||||||
{
|
{
|
||||||
FILE *fd = 0;
|
FILE *fd = NULL;
|
||||||
int i, size;
|
int h, i, size, w;
|
||||||
unsigned long io;
|
unsigned long io = 0; /* silence stupid gcc(1) in the Wall mode */
|
||||||
char *name, *fontmap;
|
char *name, *fontmap;
|
||||||
char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL};
|
char *prefix[] = {"", "", FONT_PATH, FONT_PATH, NULL};
|
||||||
char *postfix[] = {"", ".fnt", "", ".fnt"};
|
char *postfix[] = {"", ".fnt", "", ".fnt"};
|
||||||
|
|
||||||
|
struct sizeinfo {
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
unsigned long io;
|
||||||
|
} sizes[] = {{8, 16, PIO_FONT8x16},
|
||||||
|
{8, 14, PIO_FONT8x14},
|
||||||
|
{8, 8, PIO_FONT8x8},
|
||||||
|
{0, 0, 0}};
|
||||||
|
|
||||||
for (i=0; prefix[i]; i++) {
|
for (i=0; prefix[i]; i++) {
|
||||||
name = mkfullname(prefix[i], filename, postfix[i]);
|
name = mkfullname(prefix[i], filename, postfix[i]);
|
||||||
fd = fopen(name, "r");
|
fd = fopen(name, "r");
|
||||||
@ -193,31 +218,57 @@ load_font(char *type, char *filename)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fd == NULL) {
|
if (fd == NULL) {
|
||||||
warn("font file not found");
|
warn("%s: can't load font file", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcmp(type, "8x8")) {
|
if (type != NULL) {
|
||||||
size = 8*256;
|
size = 0;
|
||||||
io = PIO_FONT8x8;
|
if (sscanf(type, "%dx%d", &w, &h) == 2)
|
||||||
}
|
for (i = 0; sizes[i].w != 0; i++)
|
||||||
else if (!strcmp(type, "8x14")) {
|
if (sizes[i].w == w && sizes[i].h == h) {
|
||||||
size = 14*256;
|
size = DATASIZE(sizes[i]);
|
||||||
io = PIO_FONT8x14;
|
io = sizes[i].io;
|
||||||
}
|
}
|
||||||
else if (!strcmp(type, "8x16")) {
|
|
||||||
size = 16*256;
|
if (size == 0) {
|
||||||
io = PIO_FONT8x16;
|
warnx("%s: bad font size specification", type);
|
||||||
}
|
fclose(fd);
|
||||||
else {
|
return;
|
||||||
warn("bad font size specification");
|
}
|
||||||
fclose(fd);
|
} else {
|
||||||
return;
|
/* Apply heuristics */
|
||||||
}
|
int j;
|
||||||
fontmap = (char*) malloc(size);
|
int dsize[2];
|
||||||
if (decode(fd, fontmap) != size) {
|
|
||||||
|
size = DATASIZE(sizes[0]);
|
||||||
|
fontmap = (char*) malloc(size);
|
||||||
|
dsize[0] = decode(fd, fontmap, size);
|
||||||
|
dsize[1] = fsize(fd);
|
||||||
|
free(fontmap);
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
for (i = 0; sizes[i].w != 0; i++)
|
||||||
|
if (DATASIZE(sizes[i]) == dsize[j]) {
|
||||||
|
size = dsize[j];
|
||||||
|
io = sizes[i].io;
|
||||||
|
j = 2; /* XXX */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
warnx("%s: can't guess font size", filename);
|
||||||
|
fclose(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
rewind(fd);
|
rewind(fd);
|
||||||
if (fread(fontmap, 1, size, fd) != size) {
|
}
|
||||||
warnx("bad font file");
|
|
||||||
|
fontmap = (char*) malloc(size);
|
||||||
|
if (decode(fd, fontmap, size) != size) {
|
||||||
|
rewind(fd);
|
||||||
|
if (fsize(fd) != size || fread(fontmap, 1, size, fd) != size) {
|
||||||
|
warnx("%s: bad font file", filename);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
free(fontmap);
|
free(fontmap);
|
||||||
return;
|
return;
|
||||||
@ -590,7 +641,8 @@ test_frame()
|
|||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int opt;
|
char *font, *type;
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
|
||||||
info.size = sizeof(info);
|
info.size = sizeof(info);
|
||||||
@ -608,8 +660,13 @@ main(int argc, char **argv)
|
|||||||
print_scrnmap();
|
print_scrnmap();
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
load_font(optarg,
|
type = optarg;
|
||||||
nextarg(argc, argv, &optind, 'f'));
|
font = nextarg(argc, argv, &optind, 'f', 0);
|
||||||
|
if (font == NULL) {
|
||||||
|
type = NULL;
|
||||||
|
font = optarg;
|
||||||
|
}
|
||||||
|
load_font(type, font);
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
if (sscanf(optarg, "%dx%d", &vesa_cols,
|
if (sscanf(optarg, "%dx%d", &vesa_cols,
|
||||||
|
Loading…
Reference in New Issue
Block a user