forms/source/xforms/datatypes.cxx | 78 +++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 10 deletions(-)
New commits: commit 4d8a46b819fb65ff13e306ac2c1580f87974bb6d Author: Julien Nabet <serval2...@yahoo.fr> AuthorDate: Wed Apr 19 21:04:57 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Apr 20 08:03:38 2023 +0200 Related tdf#154769: XML form, detect misformed year/month/day From https://www.w3.org/TR/xforms20/ "Data Binding Restrictions: Binds only the following list of datatypes, or datatypes derived by restriction from those in the list: xsd:duration, xsd:date, xsd:time, xsd:dateTime, xsd:gYearMonth, xsd:gYear, xsd:gMonthDay, xsd:gDay, xsd:gMonth, xsd:float, xsd:double, and xsd:decimal. " gYear: a number between 0 and 10000 From https://www.w3.org/TR/xmlschema11-2/#gYear + https://www.w3.org/TR/xmlschema11-2/#partial-implementation: "All ·minimally conforming· processors must support nonnegative ·year· values less than 10000" -> we could accept more but if other use this minimal requirement, they may wrongly consider LO as buggy here gMonth: a number between 1 and 12, not some string like 'May' (see https://www.w3.org/TR/xmlschema11-2/#gMonth) gDay: a number between 1 and 31, https://www.w3.org/TR/xmlschema11-2/#gDay The first test in lcl_getValueyear is due to the fact that a failing conversion with "o3tl::toInt32" also returns 0. So the goal is to consider this obvious case first. Change-Id: Ifd8106b55419093a0223cff6a0afb9ccd3aa5efe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150652 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/forms/source/xforms/datatypes.cxx b/forms/source/xforms/datatypes.cxx index ea71dc85af83..8e5e0b5268b3 100644 --- a/forms/source/xforms/datatypes.cxx +++ b/forms/source/xforms/datatypes.cxx @@ -27,6 +27,7 @@ #include <com/sun/star/xsd/DataTypeClass.hpp> #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp> +#include <o3tl/string_view.hxx> #include <tools/datetime.hxx> #include <rtl/math.hxx> #include <sal/log.hxx> @@ -920,21 +921,78 @@ namespace xforms initializeTypedClone( static_cast< const OShortIntegerType& >( _rCloneSource ) ); } - bool OShortIntegerType::_getValue( const OUString& value, double& fValue ) + static bool lcl_getValueYear( std::u16string_view value, double& fValue ) { - fValue = static_cast<double>(static_cast<sal_Int16>(value.toInt32())); - // TODO/eforms - // this does not care for values which do not fit into a sal_Int16, but simply - // cuts them down. A better implementation here should probably return <FALSE/> - // for those values. - // Else, we may have a situation where the UI claims an input to be valid - // (say "12345678"), while internally, and at submission time, this is cut to - // some smaller value. + if (o3tl::equalsAscii(value, "0")) + { + fValue = 0; + return true; + } + sal_Int32 int32Value = o3tl::toInt32(value); + if ( + int32Value == 0 || + int32Value < 0 || + int32Value > 10000 + ) + { + fValue = 0; + return false; + } + fValue = static_cast<double>(static_cast<sal_Int16>(int32Value)); + return true; + } - // Additionally, this of course does not care for strings which are no numbers... + static bool lcl_getValueMonth( std::u16string_view value, double& fValue ) + { + sal_Int32 int32Value = o3tl::toInt32(value); + if ( + int32Value == 0 || + int32Value < 1 || + int32Value > 12 + ) + { + fValue = 0; + return false; + } + fValue = static_cast<double>(static_cast<sal_Int16>(int32Value)); return true; } + static bool lcl_getValueDay( std::u16string_view value, double& fValue ) + { + sal_Int32 int32Value = o3tl::toInt32(value); + if ( + int32Value == 0 || + int32Value < 1 || + int32Value > 31 + ) + { + fValue = 0; + return false; + } + fValue = static_cast<double>(static_cast<sal_Int16>(int32Value)); + return true; + } + + bool OShortIntegerType::_getValue( const OUString& value, double& fValue ) + { + switch (this->getTypeClass()) + { + case css::xsd::DataTypeClass::gYear: + return lcl_getValueYear(value, fValue); + + case css::xsd::DataTypeClass::gMonth: + return lcl_getValueMonth(value, fValue); + + case css::xsd::DataTypeClass::gDay: + return lcl_getValueDay(value, fValue); + default: + // for the moment, the only types which derive from OShortIntegerType are: + // gYear, gMonth and gDay, see ODataTypeRepository ctr + return false; + } + } + OUString OShortIntegerType::typedValueAsHumanReadableString( const Any& _rValue ) const {