Prevent overflow for capability list 94/265994/4 accepted/tizen/unified/20211111.065939 submit/tizen/20211109.071249
authorJeongmo Yang <jm80.yang@samsung.com>
Wed, 3 Nov 2021 12:44:47 +0000 (21:44 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 8 Nov 2021 08:06:30 +0000 (17:06 +0900)
[Version] 0.1.9
[Issue Type] Improvement

Change-Id: Ib3bb81c0bcd4998f04bcc6ed8f797780dcfae0e7
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/camera-hal-v4l2.spec
src/hal_camera_v4l2.c

index 980d1f6..cdb0b26 100644 (file)
@@ -2,7 +2,7 @@
 
 Name:       camera-hal-v4l2
 Summary:    Tizen Camera Hal for V4L2
-Version:    0.1.8
+Version:    0.1.9
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 08b79a8..9f28a01 100644 (file)
@@ -386,6 +386,7 @@ static int __camera_get_fourcc_plane_num(int pixel_format, guint32 *fourcc, guin
 
 static void __camera_get_fps_list(int device_fd, guint32 pixel_format, int width, int height, camera_fps_list_s *fps_list)
 {
+       uint32_t fps_count = 0;
        struct v4l2_frmivalenum ival;
 
        if (device_fd < 0 || !fps_list) {
@@ -398,30 +399,32 @@ static void __camera_get_fps_list(int device_fd, guint32 pixel_format, int width
        ival.width = width;
        ival.height = height;
 
-       if (v4l2_ioctl(device_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0) {
-               LOGE("VIDIOC_ENUM_FRAMEINTERVALS failed[%d]", errno);
-               return;
-       }
+       while (v4l2_ioctl(device_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0) {
+               if (ival.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
+                       LOGE("NOT DISCRETE type[%u] for [%dx%d]", ival.type, width, height);
+                       return;
+               }
 
-       if (ival.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
-               LOGE("NOT V4L2_FRMIVAL_TYPE_DISCRETE -> [%u]", ival.type);
-               return;
-       }
+               if (ival.index++ >= FPS_COUNT_MAX) {
+                       LOGW("\t\t\t\tFramerate[i:%u][%u/%u] is available, but list is full[max:%d]",
+                               ival.index - 1, ival.discrete.denominator, ival.discrete.numerator, FPS_COUNT_MAX);
+                       continue;
+               }
 
-       do {
                LOGI("\t\t\t\tFramerate[%u/%u]", ival.discrete.denominator, ival.discrete.numerator);
-               fps_list->fps[ival.index++] = ival.discrete.denominator;
-       } while (v4l2_ioctl(device_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
+               fps_list->fps[fps_count++] = ival.discrete.denominator;
+       }
 
-       fps_list->count = ival.index;
+
+       fps_list->count = fps_count;
 }
 
 
 static int __camera_get_device_info(int device_index, int device_fd, camera_device_info_s *device_info, char *node_path)
 {
-       int i = 0;
-       int j = 0;
+       int format_index = 0;
        int format_count = 0;
+       int resolution_index = 0;
        int resolution_count = 0;
        int camera_format = 0;
        struct v4l2_fmtdesc v4l2_format;
@@ -432,12 +435,12 @@ static int __camera_get_device_info(int device_index, int device_fd, camera_devi
                return CAMERA_ERROR_INVALID_PARAMETER;
        }
 
-       LOGD("Get Supported format and resolution");
+       LOGD("Get Supported format, resolution and fps");
 
-       for (i = 0 ; ; i++) {
+       for (format_index = 0, format_count = 0 ; ; format_index++) {
                memset(&v4l2_format, 0x0, sizeof(struct v4l2_fmtdesc));
 
-               v4l2_format.index = i;
+               v4l2_format.index = format_index;
                v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
                if (v4l2_ioctl(device_fd, VIDIOC_ENUM_FMT, &v4l2_format) < 0) {
@@ -445,28 +448,37 @@ static int __camera_get_device_info(int device_index, int device_fd, camera_devi
                        break;
                }
 
-               LOGD("\tformat[%d] "FOURCC_FORMAT" (emulated:%d)",
-                       i, FOURCC_CONVERT(v4l2_format.pixelformat),
+               LOGD("\tTry [%d] format "FOURCC_FORMAT" (emulated:%d)",
+                       format_count, FOURCC_CONVERT(v4l2_format.pixelformat),
                        ((v4l2_format.flags & V4L2_FMT_FLAG_EMULATED) ? 1 : 0));
 
                if (__camera_get_format(v4l2_format.pixelformat, &camera_format) != CAMERA_ERROR_NONE)
                        continue;
 
-               device_info->format_list.formats[format_count] = camera_format;
+               if (format_count + 1 >= CAMERA_PIXEL_FORMAT_MAX) {
+                       LOGW("format list is full[max:%u], skip format[i:%u][%d]",
+                               CAMERA_PIXEL_FORMAT_MAX, v4l2_format.index, camera_format);
+                       continue;
+               }
 
-               resolution_count = 0;
+               device_info->format_list.formats[format_count++] = camera_format;
 
-               for (j = 0 ; ; j++) {
+               for (resolution_index = 0, resolution_count = 0 ; ; resolution_index++) {
                        memset(&v4l2_frame, 0x0, sizeof(struct v4l2_frmsizeenum));
 
-                       v4l2_frame.index = j;
+                       v4l2_frame.index = resolution_index;
                        v4l2_frame.pixel_format = v4l2_format.pixelformat;
 
                        if (v4l2_ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &v4l2_frame) < 0) {
-                               LOGW("\t\tframe : end of enumeration ");
+                               LOGW("\t\tframesize : end of enumeration");
                                break;
                        }
 
+                       if (resolution_count + 1 >= RESOLUTION_COUNT_MAX) {
+                               LOGW("resolution list is full, skip resolution[%ux%u]", v4l2_frame.discrete.width, v4l2_frame.discrete.height);
+                               continue;
+                       }
+
                        switch (v4l2_frame.type) {
                        case V4L2_FRMSIZE_TYPE_DISCRETE:
                                device_info->preview_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
@@ -476,9 +488,7 @@ static int __camera_get_device_info(int device_index, int device_fd, camera_devi
                                device_info->video_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
                                device_info->video_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
 
-                               resolution_count++;
-
-                               LOGD("\t\tsize[%d] %ux%u", j,
+                               LOGD("\t\tsize[%d] %ux%u", resolution_count,
                                        v4l2_frame.discrete.width,
                                        v4l2_frame.discrete.height);
 
@@ -486,18 +496,21 @@ static int __camera_get_device_info(int device_index, int device_fd, camera_devi
                                        v4l2_frame.pixel_format,
                                        v4l2_frame.discrete.width,
                                        v4l2_frame.discrete.height,
-                                       &device_info->preview_fps_list[j]);
-                               memcpy(&device_info->video_fps_list[j], &device_info->preview_fps_list[j], sizeof(camera_fps_list_s));
+                                       &device_info->preview_fps_list[resolution_count]);
+
+                               memcpy(&device_info->video_fps_list[resolution_count], &device_info->preview_fps_list[resolution_count], sizeof(camera_fps_list_s));
+
+                               resolution_count++;
                                break;
                        case V4L2_FRMSIZE_TYPE_CONTINUOUS:
-                               LOGW("\t\tsize[%d] %ux%u - %ux%u", j,
+                               LOGW("\t\tsize[%d] %ux%u - %ux%u", resolution_count,
                                        v4l2_frame.stepwise.min_width,
                                        v4l2_frame.stepwise.min_height,
                                        v4l2_frame.stepwise.max_width,
                                        v4l2_frame.stepwise.max_height);
                                break;
                        case V4L2_FRMSIZE_TYPE_STEPWISE:
-                               LOGW("\t\tsize[%d] %ux%u - %ux%u (step %ux%u)", j,
+                               LOGW("\t\tsize[%d] %ux%u - %ux%u (step %ux%u)", resolution_count,
                                        v4l2_frame.stepwise.min_width,
                                        v4l2_frame.stepwise.min_height,
                                        v4l2_frame.stepwise.max_width,
@@ -516,8 +529,6 @@ static int __camera_get_device_info(int device_index, int device_fd, camera_devi
                device_info->video_list.count = resolution_count;
 
                LOGD("\t\tresolution count [%d]", resolution_count);
-
-               format_count++;
        }
 
        device_info->index = device_index;