libcamera: controls: guard ControlInfoMap against nullptr idmap_
It's possible to construct a Camera with an unsafe controlInfo_. This is the case in the Simple pipeline, where the camera controls are not populated. With Simple, if we attempt to set a Control, we end up with a segfault because the default constructor for ControlInfoMap doesn't intialized idmap_ which is initialized at class declaration time as const ControlIdMap *idmap_ = nullptr; Add some safeguards in ControlInfoMap to handle this case. Link: https://lists.libcamera.org/pipermail/libcamera-devel/2023-April/037439.html Suggested-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
46852241a3
commit
3dc2605bda
1 changed files with 16 additions and 0 deletions
|
@ -677,6 +677,9 @@ ControlInfoMap::ControlInfoMap(Map &&info, const ControlIdMap &idmap)
|
||||||
|
|
||||||
bool ControlInfoMap::validate()
|
bool ControlInfoMap::validate()
|
||||||
{
|
{
|
||||||
|
if (!idmap_)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (const auto &ctrl : *this) {
|
for (const auto &ctrl : *this) {
|
||||||
const ControlId *id = ctrl.first;
|
const ControlId *id = ctrl.first;
|
||||||
auto it = idmap_->find(id->id());
|
auto it = idmap_->find(id->id());
|
||||||
|
@ -719,6 +722,8 @@ bool ControlInfoMap::validate()
|
||||||
*/
|
*/
|
||||||
ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id)
|
ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id)
|
||||||
{
|
{
|
||||||
|
ASSERT(idmap_);
|
||||||
|
|
||||||
return at(idmap_->at(id));
|
return at(idmap_->at(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,6 +734,8 @@ ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id)
|
||||||
*/
|
*/
|
||||||
const ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) const
|
const ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) const
|
||||||
{
|
{
|
||||||
|
ASSERT(idmap_);
|
||||||
|
|
||||||
return at(idmap_->at(id));
|
return at(idmap_->at(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,6 +746,9 @@ const ControlInfoMap::mapped_type &ControlInfoMap::at(unsigned int id) const
|
||||||
*/
|
*/
|
||||||
ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
|
ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
|
||||||
{
|
{
|
||||||
|
if (!idmap_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ControlInfoMap and its idmap have a 1:1 mapping between their
|
* The ControlInfoMap and its idmap have a 1:1 mapping between their
|
||||||
* entries, we can thus just count the matching entries in idmap to
|
* entries, we can thus just count the matching entries in idmap to
|
||||||
|
@ -755,6 +765,9 @@ ControlInfoMap::size_type ControlInfoMap::count(unsigned int id) const
|
||||||
*/
|
*/
|
||||||
ControlInfoMap::iterator ControlInfoMap::find(unsigned int id)
|
ControlInfoMap::iterator ControlInfoMap::find(unsigned int id)
|
||||||
{
|
{
|
||||||
|
if (!idmap_)
|
||||||
|
return end();
|
||||||
|
|
||||||
auto iter = idmap_->find(id);
|
auto iter = idmap_->find(id);
|
||||||
if (iter == idmap_->end())
|
if (iter == idmap_->end())
|
||||||
return end();
|
return end();
|
||||||
|
@ -770,6 +783,9 @@ ControlInfoMap::iterator ControlInfoMap::find(unsigned int id)
|
||||||
*/
|
*/
|
||||||
ControlInfoMap::const_iterator ControlInfoMap::find(unsigned int id) const
|
ControlInfoMap::const_iterator ControlInfoMap::find(unsigned int id) const
|
||||||
{
|
{
|
||||||
|
if (!idmap_)
|
||||||
|
return end();
|
||||||
|
|
||||||
auto iter = idmap_->find(id);
|
auto iter = idmap_->find(id);
|
||||||
if (iter == idmap_->end())
|
if (iter == idmap_->end())
|
||||||
return end();
|
return end();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue