Package: gqcam
Version: 0.9.1-4
X-Debbugs-CC: [EMAIL PROTECTED]
Severity: important
Tags: patch
When running gqcam on eeePC 901, the default allocated rawbuffer at gqcam.h:209
is
too small: it supports maximum of 640x480. The available buffer length is not
checked and this results a segmentation fault almost immeditely.
The info about the camera:
$ dov4l -q
dov4l v0.9, (C) 2003-2006 by [EMAIL PROTECTED]
Canonical name for this interface: CNF7129
Type of interface:
Can capture to memory
Number of radio/tv channels if appropriate: 1
Number of audio devices if appropriate: 0
Maximum capture width in pixels: 1280
Maximum capture height in pixels: 1024
Minimum capture width in pixels: 48
Minimum capture height in pixels: 32
Image size (x,y): 320, 240
VDIOCGCHAN: Invalid argument
diff -upr gqcam-0.9.1.orig/gqcam.c gqcam-0.9.1/gqcam.c
--- gqcam-0.9.1.orig/gqcam.c 2008-10-15 21:42:48.000000000 +0200
+++ gqcam-0.9.1/gqcam.c 2008-10-15 22:23:01.000000000 +0200
@@ -46,6 +46,8 @@ char version[] = VERSION;
void init_cam(struct Camera *camera)
{
+ memset(camera, 0, sizeof(*camera));
+
camera->greyscale = 0;
camera->pic = NULL;
camera->picbuff = NULL;
@@ -95,9 +97,15 @@ void get_cam_info(struct Camera *camera)
int i;
struct video_clip vid_clips[32];
- ioctl(camera->dev, VIDIOCGCAP, &camera->vid_caps);
- ioctl(camera->dev, VIDIOCGWIN, &camera->vid_win);
- ioctl(camera->dev, VIDIOCGPICT, &camera->vid_pic);
+ if (ioctl(camera->dev, VIDIOCGCAP, &camera->vid_caps) == -1) {
+ perror("ioctl(VIDIOCGCAP)");
+ }
+ if (ioctl(camera->dev, VIDIOCGWIN, &camera->vid_win) == -1) {
+ perror("ioctl(VIDIOCGWIN)");
+ }
+ if (ioctl(camera->dev, VIDIOCGPICT, &camera->vid_pic) == -1) {
+ perror("ioctl(VIDIOCGPICT)");
+ }
for (i = 0; i < 32; i++) {
vid_clips[i].x = 0;
@@ -267,6 +275,7 @@ void grab_image(struct Camera *camera)
GdkEventExpose *event;
int input_type;
struct ov511_frame temp;
+ size_t read_size;
get_cam_info(camera);
@@ -314,13 +323,25 @@ void grab_image(struct Camera *camera)
switch(input_type) {
case INPUT_YUV:
- camera->img_size = read (camera->dev, camera->rawbuffer, camera->vid_caps.maxwidth * camera->vid_caps.maxheight * 3);
+ read_size = camera->vid_caps.maxwidth * camera->vid_caps.maxheight * 3;
+ if (sizeof(camera->rawbuffer) < read_size) {
+ fprintf(stderr, "%s:%u: FATAL: rawbuffer too small to store a %ux%u picture and dynamic allocation not supported, yet\n",
+ __FILE__, __LINE__, camera->vid_caps.maxwidth, camera->vid_caps.maxheight);
+ break;
+ }
+ camera->img_size = read (camera->dev, camera->rawbuffer, read_size);
temp.width = temp.rawwidth = camera->vid_caps.maxwidth;
temp.height = temp.rawheight = camera->vid_caps.maxheight;
yuv420p_to_rgb(&temp, camera->rawbuffer, camera->picbuff, 24);
break;
case INPUT_RGB:
- camera->img_size = read (camera->dev, camera->picbuff, camera->vid_caps.maxwidth * camera->vid_caps.maxheight * 3);
+ read_size = camera->vid_caps.maxwidth * camera->vid_caps.maxheight * 3;
+ if (sizeof(camera->rawbuffer) < read_size) {
+ fprintf(stderr, "%s:%u: FATAL: rawbuffer too small to store a %ux%u picture and dynamic allocation not supported, yet\n",
+ __FILE__, __LINE__, camera->vid_caps.maxwidth, camera->vid_caps.maxheight);
+ break;
+ }
+ camera->img_size = read (camera->dev, camera->picbuff, read_size);
break;
case INPUT_JPEG:
camera->img_size = read (camera->dev, camera->rawbuffer, sizeof(camera->rawbuffer)) - JPEG_HEADER_SIZE; // TODO error management