aboutsummaryrefslogtreecommitdiff
path: root/libxsde/xsde/cxx/parser/validating
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-03-20 14:25:05 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-03-20 14:30:48 +0200
commit387d98b80d9f383c4c7708a42444472cb89dd42b (patch)
tree4233a4e5fc05c3b80a10afafd6f7647542b283bc /libxsde/xsde/cxx/parser/validating
parent92fd3c03c5123e8d886d5de642cfc8e4606d42e6 (diff)
Add extra validation for date, dateTime, and gMonthDay per XML Schema 1.1
Diffstat (limited to 'libxsde/xsde/cxx/parser/validating')
-rw-r--r--libxsde/xsde/cxx/parser/validating/date-time.cxx36
-rw-r--r--libxsde/xsde/cxx/parser/validating/date.cxx36
-rw-r--r--libxsde/xsde/cxx/parser/validating/gmonth-day.cxx23
3 files changed, 84 insertions, 11 deletions
diff --git a/libxsde/xsde/cxx/parser/validating/date-time.cxx b/libxsde/xsde/cxx/parser/validating/date-time.cxx
index 06d66e9..268d270 100644
--- a/libxsde/xsde/cxx/parser/validating/date-time.cxx
+++ b/libxsde/xsde/cxx/parser/validating/date-time.cxx
@@ -193,11 +193,7 @@ namespace xsde
day_ = 10 * (d1 - '0') + (d2 - '0');
- if (day_ < 1 || day_ > 31)
- {
- _schema_error (schema_error::invalid_date_time_value);
- return;
- }
+ // Note: day validated below.
// month
//
@@ -241,6 +237,36 @@ namespace xsde
? (-2147483647 - 1)
: -static_cast<int> (ul))
: static_cast<int> (ul);
+
+ // Validate day according to the XML Schema 1.1 specification:
+ //
+ // The day value must be no more than 30 if month is one of 4, 6, 9,
+ // or 11, no more than 28 if month is 2 and year is not divisible by
+ // 4, or is divisible by 100 but not by 400, and no more than 29 if
+ // month is 2 and year is divisible by 400, or by 4 but not by 100.
+ //
+ unsigned short max_day = 31;
+ switch (month_)
+ {
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ max_day = 30;
+ break;
+ case 2:
+ max_day = ((year_ % 400 == 0) ||
+ (year_ % 4 == 0 && year_ % 100 != 0) ? 29 : 28);
+ break;
+ default:
+ break;
+ }
+
+ if (day_ < 1 || day_ > max_day)
+ {
+ _schema_error (schema_error::invalid_date_time_value);
+ return;
+ }
}
date_time date_time_pimpl::
diff --git a/libxsde/xsde/cxx/parser/validating/date.cxx b/libxsde/xsde/cxx/parser/validating/date.cxx
index a021e4c..ec38f09 100644
--- a/libxsde/xsde/cxx/parser/validating/date.cxx
+++ b/libxsde/xsde/cxx/parser/validating/date.cxx
@@ -120,11 +120,7 @@ namespace xsde
day_ = 10 * (d1 - '0') + (d2 - '0');
- if (day_ < 1 || day_ > 31)
- {
- _schema_error (schema_error::invalid_date_value);
- return;
- }
+ // Note: day validated below.
// zone
//
@@ -165,6 +161,36 @@ namespace xsde
? (-2147483647 - 1)
: -static_cast<int> (ul))
: static_cast<int> (ul);
+
+ // Validate day according to the XML Schema 1.1 specification:
+ //
+ // The day value must be no more than 30 if month is one of 4, 6, 9,
+ // or 11, no more than 28 if month is 2 and year is not divisible by
+ // 4, or is divisible by 100 but not by 400, and no more than 29 if
+ // month is 2 and year is divisible by 400, or by 4 but not by 100.
+ //
+ unsigned short max_day = 31;
+ switch (month_)
+ {
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ max_day = 30;
+ break;
+ case 2:
+ max_day = ((year_ % 400 == 0) ||
+ (year_ % 4 == 0 && year_ % 100 != 0) ? 29 : 28);
+ break;
+ default:
+ break;
+ }
+
+ if (day_ < 1 || day_ > max_day)
+ {
+ _schema_error (schema_error::invalid_date_value);
+ return;
+ }
}
date date_pimpl::
diff --git a/libxsde/xsde/cxx/parser/validating/gmonth-day.cxx b/libxsde/xsde/cxx/parser/validating/gmonth-day.cxx
index a972855..5d5efd7 100644
--- a/libxsde/xsde/cxx/parser/validating/gmonth-day.cxx
+++ b/libxsde/xsde/cxx/parser/validating/gmonth-day.cxx
@@ -100,7 +100,28 @@ namespace xsde
day_ = 10 * (d1 - '0') + (d2 - '0');
- if (day_ < 1 || day_ > 31)
+ // Validate day according to the XML Schema 1.1 specification:
+ //
+ // The day value must be no more than 30 if month is one of 4, 6, 9,
+ // or 11, and no more than 29 if month is 2.
+ //
+ unsigned short max_day = 31;
+ switch (month_)
+ {
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ max_day = 30;
+ break;
+ case 2:
+ max_day = 29;
+ break;
+ default:
+ break;
+ }
+
+ if (day_ < 1 || day_ > max_day)
{
_schema_error (schema_error::invalid_gmonth_day_value);
return;