From patchwork Fri Dec 30 00:23:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 18080 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id A5CE2C3220 for ; Fri, 30 Dec 2022 00:23:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C6468625CF; Fri, 30 Dec 2022 01:23:15 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1672359795; bh=cj+q4I3GI2lJqodNA3mfw9WbdHyR7aIfFp/y/6PZgYs=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=gl1j5mMq8uf+GjGvsSU/koPP5TsjnO7POhTe/pEpA6Ti/Uhrwow0M3vzn8NBnDni/ cxtekFPh6ezTJyhIHFvk/bANFk0Z5IL+19dse1oQy6qE4yIlsdnpuEwruhHefSZWjY zIrdeOw/ctD7CPSTfPh2RSXOqTOMV12i5lfuK8z1LjJHrO6eTFraclSBTsxkFdAgRN 5s4Ne8w4+jdj+oUhdqT2oJL1W/Gm5EI2bBZaQeDoeQEoDepDgz66TuInkwrWDX7Ebg YKKDBE2iNa+HvrPk2A9FX8RvjOlBqjSxBN1Q7F+Wf0J3apcToDtKnu/J/3JhGRAg4R lL4I18rBVNBsQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4E76261F13 for ; Fri, 30 Dec 2022 01:23:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VnpLt7kK"; dkim-atps=neutral Received: from Monstersaurus.local (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A2B886D0; Fri, 30 Dec 2022 01:23:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1672359792; bh=cj+q4I3GI2lJqodNA3mfw9WbdHyR7aIfFp/y/6PZgYs=; h=From:To:Cc:Subject:Date:From; b=VnpLt7kK4wK6jMBcX5JZpK2cyLahTx0uhrz7d1yDaZ6AnKoO1kx1U1BAhI3Kds9QY nIbJqOZnRoCtOacEB8xW33qrgmtwFGg6sPw9b9dP0E2XWaWhtdb1agTqwROkbNndCn xMM9t5uD6KMTkVjaXDRrr3tZ8ntGX7Mi7VM201yI= To: libcamera devel Date: Fri, 30 Dec 2022 00:23:09 +0000 Message-Id: <20221230002309.3135078-1-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2] libcamera: yaml_parser: Use C locale X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Kieran Bingham via libcamera-devel From: Kieran Bingham Reply-To: Kieran Bingham Cc: Hannes Winkler Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" When parsing configuration files on systems with differing locales, the use of strtod can produce different results, or in the worst case - fail to parse expected values. Provide an RAII implementation to construct a locale specific to the expected mappings for configuration files provided by libcamera. Bug: https://bugs.libcamera.org/show_bug.cgi?id=174 Bug: https://github.com/raspberrypi/libcamera/issues/29 Reported-by: https://github.com/kralo Reported-by: Hannes Winkler Reviewed-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- v2: - use const char * over std::string - use C++ static casts - fix blank lines Signed-off-by: Kieran Bingham --- src/libcamera/yaml_parser.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index d8a7c2f9250f..c7fd80cdea1b 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -31,6 +31,38 @@ namespace { /* Empty static YamlObject as a safe result for invalid operations */ static const YamlObject empty; +/* + * Construct a global RAII locale for use by all YAML parser instances to + * ensure consistency when parsing configuration files and types regardless of + * the host Locale configuration. + * + * For more information see: + * - https://bugs.libcamera.org/show_bug.cgi?id=174 + */ +class Locale +{ +public: + Locale(const char *locale) + { + locale_ = newlocale(LC_ALL_MASK, locale, static_cast(0)); + if (locale_ == static_cast(0)) + LOG(YamlParser, Fatal) + << "Failed to construct a locale"; + } + + ~Locale() + { + freelocale(locale_); + } + + locale_t locale() { return locale_; } + +private: + locale_t locale_; +}; + +static Locale yamlLocale("C"); + } /* namespace */ /** @@ -283,7 +315,7 @@ std::optional YamlObject::get() const char *end; errno = 0; - double value = std::strtod(value_.c_str(), &end); + double value = strtod_l(value_.c_str(), &end, yamlLocale.locale()); if ('\0' != *end || errno == ERANGE) return std::nullopt;