[PATCH] libcamera: base: Fix log level parsing when multiple categories are listed
Barnabás Pőcze
barnabas.pocze at ideasonboard.com
Fri Jun 6 11:11:03 CEST 2025
2025. 06. 06. 10:37 keltezéssel, Stefan Klug írta:
> For a list of log levels like LIBCAMERA_LOG_LEVELS="CatA:0,CatB:1" only
> the severity of the last entry is correctly parsed.
>
> Due to the change of level to a string_view in 24c2caa1c1b3 ("libcamera:
> base: log: Use `std::string_view` to avoid some copies") the level is no
> longer necessarily null terminated as it is a view on the original data.
>
> Replace the check for a terminating null by a check for the end position
> to fix the issue.
Oops, sorry. I hope it wasn't too hard to find.
>
> Fixes: 24c2caa1c1b3 ("libcamera: base: log: Use `std::string_view` to avoid some copies")
> Signed-off-by: Stefan Klug <stefan.klug at ideasonboard.com>
> ---
> src/libcamera/base/log.cpp | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/src/libcamera/base/log.cpp b/src/libcamera/base/log.cpp
> index 8bf3e1daa9c6..e024b58d7180 100644
> --- a/src/libcamera/base/log.cpp
> +++ b/src/libcamera/base/log.cpp
> @@ -690,8 +690,9 @@ LogSeverity Logger::parseLogLevel(std::string_view level)
> unsigned int severity = LogInvalid;
>
> if (std::isdigit(level[0])) {
> - auto [end, ec] = std::from_chars(level.data(), level.data() + level.size(), severity);
> - if (ec != std::errc() || *end != '\0' || severity > LogFatal)
> + const char* levelEnd = level.data() + level.size();
const char *levelEnd ?
Could a test be added? Maybe something like this:
---
diff --git a/test/log/log_api.cpp b/test/log/log_api.cpp
index 0b999738d..8587ea30d 100644
--- a/test/log/log_api.cpp
+++ b/test/log/log_api.cpp
@@ -26,10 +26,42 @@ using namespace std;
using namespace libcamera;
LOG_DEFINE_CATEGORY(LogAPITest)
+LOG_DEFINE_CATEGORY(Cat0)
+LOG_DEFINE_CATEGORY(Cat1)
+LOG_DEFINE_CATEGORY(Cat2)
+LOG_DEFINE_CATEGORY(Cat3)
+LOG_DEFINE_CATEGORY(Cat4)
class LogAPITest : public Test
{
protected:
+ int testEnvLevels()
+ {
+ setenv("LIBCAMERA_LOG_LEVELS",
+ "Cat0:0,Cat0:9999,Cat1:INFO,Cat1:INVALID,Cat2:2,Cat2:-1,Cat3:ERROR,Cat3:{[]},Cat4:4,Cat4:rubbish",
+ true);
+ logSetTarget(libcamera::LoggingTargetNone);
+
+ const std::pair<const LogCategory &, libcamera::LogSeverity> expected[] = {
+ { _LOG_CATEGORY(Cat0)(), libcamera::LogDebug },
+ { _LOG_CATEGORY(Cat1)(), libcamera::LogInfo },
+ { _LOG_CATEGORY(Cat2)(), libcamera::LogWarning },
+ { _LOG_CATEGORY(Cat3)(), libcamera::LogError },
+ { _LOG_CATEGORY(Cat4)(), libcamera::LogFatal },
+ };
+ bool ok = true;
+
+ for (const auto &[c, s] : expected) {
+ if (c.severity() != s) {
+ ok = false;
+ cerr << "Severity of " << c.name() << " (" << c.severity() << ") "
+ << "does not equal " << s << endl;
+ }
+ }
+
+ return ok ? TestPass : TestFail;
+ }
+
void doLogging()
{
logSetLevel("LogAPITest", "DEBUG");
@@ -135,7 +167,11 @@ protected:
int run() override
{
- int ret = testFile();
+ int ret = testEnvLevels();
+ if (ret != TestPass)
+ return TestFail;
+
+ ret = testFile();
if (ret != TestPass)
return TestFail;
---
Reviewed-by: Barnabás Pőcze <barnabas.pocze at ideasonboard.com>
> + auto [end, ec] = std::from_chars(level.data(), levelEnd, severity);
> + if (ec != std::errc() || end != levelEnd || severity > LogFatal)
> severity = LogInvalid;
> } else {
> for (unsigned int i = 0; i < std::size(names); ++i) {
More information about the libcamera-devel
mailing list