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