Resolves: tdf#106956 CDateFromIso accept also YYYY-MM-DD form

Previous implementation was over-simplified and accepted all sort of malformed
input to yield some arbitrary date, including longer and shorter and not
strictly numeric strings.

Change-Id: I2158429aeff7431f5ec5a1c9125018a5455a4730
This commit is contained in:
Eike Rathke
2017-04-28 15:37:17 +02:00
parent 3d0cbe3e7b
commit cdcbdf88b7

View File

@@ -2045,31 +2045,64 @@ RTLFUNC(CDateToIso)
}
}
// Function to convert date from ISO 8601 date format
// Function to convert date from ISO 8601 date format YYYYMMDD or YYYY-MM-DD
RTLFUNC(CDateFromIso)
{
(void)pBasic;
(void)bWrite;
if ( rPar.Count() == 2 )
do
{
if ( rPar.Count() != 2 )
break;
OUString aStr = rPar.Get(1)->GetOUString();
const sal_Int32 iMonthStart = aStr.getLength() - 4;
OUString aYearStr = aStr.copy( 0, iMonthStart );
OUString aMonthStr = aStr.copy( iMonthStart, 2 );
OUString aDayStr = aStr.copy( iMonthStart+2, 2 );
const sal_Int32 nLen = aStr.getLength();
if (nLen != 8 && nLen != 10)
break;
OUString aYearStr, aMonthStr, aDayStr;
if (nLen == 8)
{
// YYYYMMDD
if (!comphelper::string::isdigitAsciiString(aStr))
break;
aYearStr = aStr.copy( 0, 4 );
aMonthStr = aStr.copy( 4, 2 );
aDayStr = aStr.copy( 6, 2 );
}
else
{
// YYYY-MM-DD
const sal_Int32 nSep1 = aStr.indexOf('-');
if (nSep1 != 4)
break;
const sal_Int32 nSep2 = aStr.indexOf('-', nSep1+1);
if (nSep2 != 7)
break;
aYearStr = aStr.copy( 0, 4 );
aMonthStr = aStr.copy( 5, 2 );
aDayStr = aStr.copy( 8, 2 );
if ( !comphelper::string::isdigitAsciiString(aYearStr) ||
!comphelper::string::isdigitAsciiString(aMonthStr) ||
!comphelper::string::isdigitAsciiString(aDayStr))
break;
}
double dDate;
if( implDateSerial( (sal_Int16)aYearStr.toInt32(),
(sal_Int16)aMonthStr.toInt32(), (sal_Int16)aDayStr.toInt32(), dDate ) )
{
rPar.Get(0)->PutDate( dDate );
}
}
else
{
StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
if (!implDateSerial( (sal_Int16)aYearStr.toInt32(),
(sal_Int16)aMonthStr.toInt32(), (sal_Int16)aDayStr.toInt32(), dDate ))
break;
rPar.Get(0)->PutDate( dDate );
return;
}
while (false);
StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
}
RTLFUNC(DateSerial)