2000-09-30 Henning Meier-Geinitz <hmg@gmx.de>

* backend/pnm.c: Fixed three segfaults due to buffer overruns:
 	  maximum length of filename wasn't checked; maximum length in
 	  sane_read wasn't always checked; ppm_type wasn't always set in
 	  getparmfromfile. Added some checks for safety and removal of
 	  warnings. Added DBG lines for every SANE API call.
	* TODO: Added entries about the backend:devicename issue. Add a
	  comment about fronends not to crash when length is -1. Added entry
 	  about sane-pie. Added point about fronends not checking if too
	  much data is delivered with sane_read.
	* PROJECTS: Added entry about sane-pie.
DEVEL_2_0_BRANCH-1
Henning Geinitz 2000-09-30 13:41:16 +00:00
rodzic 1adff27a7a
commit 070adee264
2 zmienionych plików z 47 dodań i 14 usunięć

Wyświetl plik

@ -58,13 +58,17 @@ Henning Meier-Geinitz <hmg@gmx.de>
NEC PC-IN500/4C support (wip) NEC PC-IN500/4C support (wip)
<fukuda@pjs.nevt.nec.co.jp> <fukuda@pjs.nevt.nec.co.jp>
Pacific Image Electronics series of ScanAce SCSI scanners, and the Devcom
9636/9630 BlackWidow support (wip)
http://www.munton.demon.co.uk/sane
Polaroid SprintScan 35 LE (wip) Polaroid SprintScan 35 LE (wip)
Dick Bruijn <dick@wau.mis.ah.nl> Dick Bruijn <dick@wau.mis.ah.nl>
Primax parallel port scanners (wip) Primax parallel port scanners (wip)
http://primax.sourceforge.net/ http://primax.sourceforge.net/
SGI IndyCam (wip?) SGI IndyCam (wip)
Erik Nygren <nygren@mit.edu> Erik Nygren <nygren@mit.edu>
Video for Linux 2 (wip) Video for Linux 2 (wip)

Wyświetl plik

@ -53,13 +53,17 @@
#define BACKEND_NAME pnm #define BACKEND_NAME pnm
#include "sane/sanei_backend.h" #include "sane/sanei_backend.h"
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
#define MAGIC (void *)0xab730324 #define MAGIC (void *)0xab730324
static int is_open = 0; static int is_open = 0;
static int three_pass = 0; static int three_pass = 0;
static int hand_scanner = 0; static int hand_scanner = 0;
static int pass = 0; static int pass = 0;
static char filename[128] = "/tmp/input.ppm"; static char filename[PATH_MAX] = "/tmp/input.ppm";
static SANE_Fixed bright = 0; static SANE_Fixed bright = 0;
static SANE_Fixed contr = 0; static SANE_Fixed contr = 0;
static SANE_Bool gray = SANE_FALSE; static SANE_Bool gray = SANE_FALSE;
@ -212,7 +216,8 @@ SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{ {
DBG_INIT(); DBG_INIT();
DBG(2, "sane_init: version_code %s 0, authorize %s 0\n",
version_code == 0 ? "=" : "!=", authorize == 0 ? "=" : "!=");
if (version_code) if (version_code)
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0); *version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0);
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
@ -221,6 +226,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
void void
sane_exit (void) sane_exit (void)
{ {
DBG(2, "sane_exit\n");
} }
/* Device select/open/close */ /* Device select/open/close */
@ -249,6 +255,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
dev + 0, dev + 1, 0 dev + 0, dev + 1, 0
}; };
DBG(2, "sane_get_devices: local_only = %d\n", local_only);
*device_list = devlist; *device_list = devlist;
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
@ -258,6 +265,10 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{ {
int i; int i;
if (!devicename)
return SANE_STATUS_INVAL;
DBG(2, "sane_open: devicename = \"%s\"\n", devicename);
if (!devicename[0]) if (!devicename[0])
i = 0; i = 0;
else else
@ -278,6 +289,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
void void
sane_close (SANE_Handle handle) sane_close (SANE_Handle handle)
{ {
DBG(2, "sane_close\n");
if (handle == MAGIC) if (handle == MAGIC)
is_open = 0; is_open = 0;
} }
@ -285,6 +297,7 @@ sane_close (SANE_Handle handle)
const SANE_Option_Descriptor * const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
{ {
DBG(2, "sane_get_option_descriptor: option = %d\n", option);
if (handle != MAGIC || !is_open) if (handle != MAGIC || !is_open)
return NULL; /* wrong device */ return NULL; /* wrong device */
if (option < 0 || option >= NELEMS(sod)) if (option < 0 || option >= NELEMS(sod))
@ -300,7 +313,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
SANE_Int myinfo = 0; SANE_Int myinfo = 0;
SANE_Status status; SANE_Status status;
DBG(2, "control_option(handle=%p,opt=%d,act=%d,val=%p,info=%p)\n", DBG(2, "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n",
handle, option, action, value, info); handle, option, action, value, info);
if (handle != MAGIC || !is_open) if (handle != MAGIC || !is_open)
@ -319,6 +332,8 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
switch (option) switch (option)
{ {
case 2: case 2:
if ((strlen (value) + 1) > sizeof (filename))
return SANE_STATUS_NO_MEM;
strcpy (filename, value); strcpy (filename, value);
if (access (filename, R_OK) == 0) if (access (filename, R_OK) == 0)
myinfo |= SANE_INFO_RELOAD_PARAMS; myinfo |= SANE_INFO_RELOAD_PARAMS;
@ -414,19 +429,23 @@ getparmfromfile (void)
{ {
/* Binary monochrome. */ /* Binary monochrome. */
parms.depth = 1; parms.depth = 1;
gray = SANE_TRUE;
ppm_type = ppm_bitmap; ppm_type = ppm_bitmap;
} }
else if (!strncmp (buf, "P5", 2)) else if (!strncmp (buf, "P5", 2))
{ {
/* Grayscale. */ /* Grayscale. */
gray = SANE_TRUE; parms.depth = 8;
ppm_type = ppm_greyscale; ppm_type = ppm_greyscale;
} }
else if (strncmp (buf, "P6", 2)) else if (!strncmp (buf, "P6", 2))
{ {
DBG(2, "%s is not a recognized PPM\n", filename); /* Color. */
parms.depth = 8;
ppm_type = ppm_color;
}
else
{
DBG(1, "getparmfromfile: %s is not a recognized PPM\n", filename);
fclose (fn); fclose (fn);
return -1; return -1;
} }
@ -444,7 +463,7 @@ getparmfromfile (void)
parms.lines = -1; parms.lines = -1;
else else
parms.lines = y; parms.lines = y;
if (gray) if ((ppm_type == ppm_greyscale) || (ppm_type == ppm_bitmap) || gray)
parms.format = SANE_FRAME_GRAY; parms.format = SANE_FRAME_GRAY;
else else
{ {
@ -468,6 +487,7 @@ sane_get_parameters (SANE_Handle handle,
SANE_Parameters * params) SANE_Parameters * params)
{ {
int rc = SANE_STATUS_GOOD; int rc = SANE_STATUS_GOOD;
DBG(2, "sane_get_parameters\n");
if (handle != MAGIC || !is_open) if (handle != MAGIC || !is_open)
rc = SANE_STATUS_INVAL; /* Unknown handle ... */ rc = SANE_STATUS_INVAL; /* Unknown handle ... */
else if (getparmfromfile ()) else if (getparmfromfile ())
@ -482,6 +502,7 @@ sane_start (SANE_Handle handle)
char buf[1024]; char buf[1024];
int nlines; int nlines;
DBG(2, "sane_start\n");
if (handle != MAGIC || !is_open) if (handle != MAGIC || !is_open)
return SANE_STATUS_INVAL; /* Unknown handle ... */ return SANE_STATUS_INVAL; /* Unknown handle ... */
@ -522,7 +543,9 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
{ {
int len, x, hlp; int len, x, hlp;
if (handle != MAGIC || !is_open || !infile) DBG(2,"sane_read: max_length = %d, rgbleftover = {%d, %d, %d}\n",
max_length, rgbleftover[0], rgbleftover[1], rgbleftover[2]);
if (handle != MAGIC || !is_open || !infile || !data || !length)
return SANE_STATUS_INVAL; /* Unknown handle or no file to read... */ return SANE_STATUS_INVAL; /* Unknown handle or no file to read... */
if (feof (infile)) if (feof (infile))
@ -542,6 +565,7 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
if (rgbbuf == 0) if (rgbbuf == 0)
return SANE_STATUS_NO_MEM; return SANE_STATUS_NO_MEM;
} }
else rgblength = 3 * max_length;
/* Copy any leftovers into the buffer. */ /* Copy any leftovers into the buffer. */
q = rgbbuf; q = rgbbuf;
@ -603,6 +627,7 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
void void
sane_cancel (SANE_Handle handle) sane_cancel (SANE_Handle handle)
{ {
DBG(2, "sane_cancel: handle = %p\n", handle);
pass = 0; pass = 0;
if (infile != NULL) if (infile != NULL)
{ {
@ -614,11 +639,15 @@ sane_cancel (SANE_Handle handle)
SANE_Status SANE_Status
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{ {
DBG(2, "sane_set_io_mode: handle = %p, non_blocking = %d\n", handle,
non_blocking);
return SANE_STATUS_UNSUPPORTED; return SANE_STATUS_UNSUPPORTED;
} }
SANE_Status SANE_Status
sane_get_select_fd (SANE_Handle handle, SANE_Int * fd) sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
{ {
DBG(2, "sane_get_select_fd: handle = %p, fd %s 0\n", handle,
fd ? "!=" : "=");
return SANE_STATUS_UNSUPPORTED; return SANE_STATUS_UNSUPPORTED;
} }