[libcamera-devel] libcamera: pipeline: uvcvideo: Fix crash when default entity is not found

Message ID 20200102000306.633-1-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • [libcamera-devel] libcamera: pipeline: uvcvideo: Fix crash when default entity is not found
Related show

Commit Message

Laurent Pinchart Jan. 2, 2020, 12:03 a.m. UTC
Commit e441f2c7f46d ("libcamera: pipeline: uvcvideo: Add controls
support") broke handling of UVC devices without a default entity by
turning the error check into an always false check. Fix it.

Fixes: e441f2c7f46d ("libcamera: pipeline: uvcvideo: Add controls support")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/libcamera/pipeline/uvcvideo.cpp | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

Comments

Paul Elder Jan. 3, 2020, 5:15 a.m. UTC | #1
Hi Laurent,

Thank you for the patch.

On Thu, Jan 02, 2020 at 02:03:06AM +0200, Laurent Pinchart wrote:
> Commit e441f2c7f46d ("libcamera: pipeline: uvcvideo: Add controls
> support") broke handling of UVC devices without a default entity by
> turning the error check into an always false check. Fix it.
> 
> Fixes: e441f2c7f46d ("libcamera: pipeline: uvcvideo: Add controls support")
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  src/libcamera/pipeline/uvcvideo.cpp | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
> index 3043366bee38..8d7f7ea79410 100644
> --- a/src/libcamera/pipeline/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo.cpp
> @@ -296,19 +296,19 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
>  	std::unique_ptr<UVCCameraData> data = utils::make_unique<UVCCameraData>(this);
>  
>  	/* Locate and initialise the camera data with the default video node. */
> -	for (MediaEntity *entity : media->entities()) {
> -		if (entity->flags() & MEDIA_ENT_FL_DEFAULT) {
> -			if (data->init(entity))
> -				return false;
> -			break;
> -		}
> -	}
> -
> -	if (!data) {
> +	const std::vector<MediaEntity *> &entities = media->entities();
> +	auto entity = std::find_if(entities.begin(), entities.end(),
> +				   [](MediaEntity *entity) {
> +					return entity->flags() & MEDIA_ENT_FL_DEFAULT;
> +				   });
> +	if (entity == entities.end()) {
>  		LOG(UVC, Error) << "Could not find a default video device";
>  		return false;
>  	}
>  
> +	if (data->init(*entity))
> +		return false;
> +
>  	/* Create and register the camera. */
>  	std::set<Stream *> streams{ &data->stream_ };
>  	std::shared_ptr<Camera> camera = Camera::create(this, media->model(), streams);

Looks good to me.

Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Jacopo Mondi Jan. 3, 2020, 8:34 a.m. UTC | #2
Hi Laurent,

On Thu, Jan 02, 2020 at 02:03:06AM +0200, Laurent Pinchart wrote:
> Commit e441f2c7f46d ("libcamera: pipeline: uvcvideo: Add controls
> support") broke handling of UVC devices without a default entity by
> turning the error check into an always false check. Fix it.
>
> Fixes: e441f2c7f46d ("libcamera: pipeline: uvcvideo: Add controls support")
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

> ---
>  src/libcamera/pipeline/uvcvideo.cpp | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
> index 3043366bee38..8d7f7ea79410 100644
> --- a/src/libcamera/pipeline/uvcvideo.cpp
> +++ b/src/libcamera/pipeline/uvcvideo.cpp
> @@ -296,19 +296,19 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
>  	std::unique_ptr<UVCCameraData> data = utils::make_unique<UVCCameraData>(this);
>
>  	/* Locate and initialise the camera data with the default video node. */
> -	for (MediaEntity *entity : media->entities()) {
> -		if (entity->flags() & MEDIA_ENT_FL_DEFAULT) {
> -			if (data->init(entity))
> -				return false;
> -			break;
> -		}
> -	}
> -
> -	if (!data) {
> +	const std::vector<MediaEntity *> &entities = media->entities();
> +	auto entity = std::find_if(entities.begin(), entities.end(),
> +				   [](MediaEntity *entity) {
> +					return entity->flags() & MEDIA_ENT_FL_DEFAULT;
> +				   });
> +	if (entity == entities.end()) {
>  		LOG(UVC, Error) << "Could not find a default video device";
>  		return false;
>  	}
>
> +	if (data->init(*entity))
> +		return false;
> +
>  	/* Create and register the camera. */
>  	std::set<Stream *> streams{ &data->stream_ };
>  	std::shared_ptr<Camera> camera = Camera::create(this, media->model(), streams);
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 3043366bee38..8d7f7ea79410 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -296,19 +296,19 @@  bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 	std::unique_ptr<UVCCameraData> data = utils::make_unique<UVCCameraData>(this);
 
 	/* Locate and initialise the camera data with the default video node. */
-	for (MediaEntity *entity : media->entities()) {
-		if (entity->flags() & MEDIA_ENT_FL_DEFAULT) {
-			if (data->init(entity))
-				return false;
-			break;
-		}
-	}
-
-	if (!data) {
+	const std::vector<MediaEntity *> &entities = media->entities();
+	auto entity = std::find_if(entities.begin(), entities.end(),
+				   [](MediaEntity *entity) {
+					return entity->flags() & MEDIA_ENT_FL_DEFAULT;
+				   });
+	if (entity == entities.end()) {
 		LOG(UVC, Error) << "Could not find a default video device";
 		return false;
 	}
 
+	if (data->init(*entity))
+		return false;
+
 	/* Create and register the camera. */
 	std::set<Stream *> streams{ &data->stream_ };
 	std::shared_ptr<Camera> camera = Camera::create(this, media->model(), streams);