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
     {

Reply via email to