Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ad97a72
Refactor: libcrmcommon: Clarify days_in_month_year()
nrwahl2 Apr 11, 2026
abfe777
Refactor: libcrmcommon: Use g_date_get_days_in_month()
nrwahl2 Apr 12, 2026
074fa4a
Log: libcrmcommon: Drop unhelpful trace logs from crm_time_add_months()
nrwahl2 Apr 12, 2026
d417481
Refactor: libcrmcommon: Rename a_time and value variables in crm_time.c
nrwahl2 Apr 12, 2026
2aed776
Refactor: libcrmcommon: Rename ymd variables in crm_time_add_months()
nrwahl2 Apr 12, 2026
51dfb80
Refactor: libcrmcommon: Assert before dereferencing in iso8601.c
nrwahl2 Apr 12, 2026
56028a9
Refactor: libcrmcommon: Improve variable names in get_ordinal_days()
nrwahl2 Apr 11, 2026
a3d3d06
Refactor: libcrmcommon: Drop redundant check from parse_int()
nrwahl2 Apr 12, 2026
4136b05
Refactor: libcrmcommon: Functionizing parsing a duration element
nrwahl2 Apr 12, 2026
1f5a24f
Refactor: libcrmcommon: Drop some nesting in parse_duration_element()
nrwahl2 Apr 12, 2026
4d13563
Log: libcrmcommon: Improve no-units message in parse_duration_element()
nrwahl2 Apr 12, 2026
8be47a0
Log: libcrmcommon: Simplify overflow logging in parse_duration_element()
nrwahl2 Apr 12, 2026
5b715eb
Low: libcrmcommon: Improve crm_time_get_seconds() for durations
nrwahl2 Apr 12, 2026
82b4730
Refactor: libcrmcommon: Use g_date_is_leap_year()
nrwahl2 Apr 12, 2026
8b3bd5b
Doc: libcrmcommon: Address FIXME comment about GLib version
nrwahl2 Apr 12, 2026
17e4629
Refactor: libcrmcommon: New offset_text()
nrwahl2 Apr 12, 2026
b1f822a
Refactor: libcrmcommon: seconds_to_hms() accepts NULL seconds
nrwahl2 Apr 12, 2026
9f975cc
Refactor: tools: Drop redundant else in crm_rule.c
nrwahl2 Apr 13, 2026
fc37918
Refactor: libcrmcommon: Remove some nesting in set_effective_date()
nrwahl2 Apr 16, 2026
c2d21cd
Refactor: libpacemaker: Improve validation in set_effective_date()
nrwahl2 Apr 17, 2026
c3d4f3f
Refactor: libcrmcommon: Cast -1 to time_t for comparison
nrwahl2 Apr 26, 2026
6bf377a
Test: cts-cli: Test out-of-range year in interval specification
nrwahl2 Apr 27, 2026
49c9040
Feature: libcrmcommon: crm_time_parse_period requires years in [1, 9999]
nrwahl2 Apr 27, 2026
8be01c8
Refactor: tools: iso8601 output function doesn't use crm_time_period_t
nrwahl2 Apr 27, 2026
bd3d2fe
Refactor: tools: Drop crm_time_period_t from iso8601 CLI tool
nrwahl2 Apr 27, 2026
ef38ab1
API: libcrmcommon: Deprecate crm_time_parse_period()
nrwahl2 Apr 27, 2026
f3f3815
API: libcrmcommon: Deprecate crm_time_free_period()
nrwahl2 Apr 27, 2026
73da0e8
API: libcrmcommon: Deprecate crm_time_period_t
nrwahl2 Apr 27, 2026
e254aec
Feature: tools: crm_rule requires dates to have year between 1 and 9999
nrwahl2 Apr 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions cts/cli/regression.dates.exp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
=#=#=#= Begin test: Invalid period - [] =#=#=#=
crm_time_parse_period error: No ISO 8601 time period given
parse_period error: No ISO 8601 time period given
iso8601: Invalid interval specified:
=#=#=#= End test: Invalid period - [] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - []
=#=#=#= Begin test: Invalid period - [2019-01-01 00:00:00Z] =#=#=#=
crm_time_parse_period error: '2019-01-01 00:00:00Z' is not a valid ISO 8601 time period because it has no duration or ending time
parse_period error: '2019-01-01 00:00:00Z' is not a valid ISO 8601 time period because it has no duration or ending time
iso8601: Invalid interval specified: 2019-01-01 00:00:00Z
=#=#=#= End test: Invalid period - [2019-01-01 00:00:00Z] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [2019-01-01 00:00:00Z]
Expand All @@ -14,7 +14,7 @@ iso8601: Invalid interval specified: 2019-01-01 00:00:00Z/
=#=#=#= End test: Invalid period - [2019-01-01 00:00:00Z/] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [2019-01-01 00:00:00Z/]
=#=#=#= Begin test: Invalid period - [PT2S/P1M] =#=#=#=
crm_time_parse_period error: 'PT2S/P1M' is not a valid ISO 8601 time period because it has two durations
parse_period error: 'PT2S/P1M' is not a valid ISO 8601 time period because it has two durations
iso8601: Invalid interval specified: PT2S/P1M
=#=#=#= End test: Invalid period - [PT2S/P1M] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [PT2S/P1M]
Expand Down Expand Up @@ -69,15 +69,30 @@ iso8601: Invalid interval specified: 2019-01-01 00:00:00Z/P
=#=#=#= End test: Invalid period - [2019-01-01 00:00:00Z/P] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [2019-01-01 00:00:00Z/P]
=#=#=#= Begin test: Invalid period - [P1Z/2019-02-20 00:00:00Z] =#=#=#=
crm_time_parse_duration error: 'P1Z/2019-02-20 00:00:00Z' is not a valid ISO 8601 time duration because 'Z' is not a valid time unit
parse_duration_element error: 'P1Z/2019-02-20 00:00:00Z' is not a valid ISO 8601 duration because 'Z' is not a valid time unit
iso8601: Invalid interval specified: P1Z/2019-02-20 00:00:00Z
=#=#=#= End test: Invalid period - [P1Z/2019-02-20 00:00:00Z] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [P1Z/2019-02-20 00:00:00Z]
=#=#=#= Begin test: Invalid period - [P1YM/2019-02-20 00:00:00Z] =#=#=#=
crm_time_parse_duration error: 'P1YM/2019-02-20 00:00:00Z' is not a valid ISO 8601 time duration because no valid integer at 'M/2019-02-20 00:00:00Z'
parse_duration_element error: 'P1YM/2019-02-20 00:00:00Z' is not a valid ISO 8601 duration because no valid integer at 'M/2019-02-20 00:00:00Z'
iso8601: Invalid interval specified: P1YM/2019-02-20 00:00:00Z
=#=#=#= End test: Invalid period - [P1YM/2019-02-20 00:00:00Z] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [P1YM/2019-02-20 00:00:00Z]
=#=#=#= Begin test: Invalid period - [0000-10-01T00:00:00Z/P1M] =#=#=#=
parse_date error: '0000-10-01T00:00:00Z/P1M' is not a valid ISO 8601 date/time specification because '0' is not a valid year
iso8601: Invalid interval specified: 0000-10-01T00:00:00Z/P1M
=#=#=#= End test: Invalid period - [0000-10-01T00:00:00Z/P1M] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [0000-10-01T00:00:00Z/P1M]
=#=#=#= Begin test: Invalid period - [-0001-10-01T00:00:00Z/P1M] =#=#=#=
parse_date error: '-0001-10-01T00:00:00Z/P1M' is not a valid ISO 8601 date/time specification because '4294967295' is not a valid year
iso8601: Invalid interval specified: -0001-10-01T00:00:00Z/P1M
=#=#=#= End test: Invalid period - [-0001-10-01T00:00:00Z/P1M] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [-0001-10-01T00:00:00Z/P1M]
=#=#=#= Begin test: Invalid period - [10000-10-01T00:00:00Z/P1M] =#=#=#=
parse_period error: 'P1M' is not a valid ISO 8601 time period because the start is invalid (must be between 0001-01-01T00:00:00 and 9999-12-31T23:59:59)
iso8601: Invalid interval specified: 10000-10-01T00:00:00Z/P1M
=#=#=#= End test: Invalid period - [10000-10-01T00:00:00Z/P1M] - Invalid parameter (2) =#=#=#=
* Passed: iso8601 - Invalid period - [10000-10-01T00:00:00Z/P1M]
=#=#=#= Begin test: '2005-040/2005-043' period =#=#=#=
Period: 2005-02-09 00:00:00Z to 2005-02-12 00:00:00Z
=#=#=#= End test: '2005-040/2005-043' period - OK (0) =#=#=#=
Expand Down
8 changes: 6 additions & 2 deletions cts/cts-cli.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# We know this is a very long file.
# pylint: disable=too-many-lines

__copyright__ = "Copyright 2024-2025 the Pacemaker project contributors"
__copyright__ = "Copyright 2024-2026 the Pacemaker project contributors"
__license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY"

import argparse
Expand Down Expand Up @@ -252,7 +252,6 @@ def sanitize_output(s):
(r'crm_feature_set="[^"]*" ', r''),
(r'@crm_feature_set=[0-9.]+, ', r''),
(r'\(crm_time_parse_duration@.*\.c:[0-9]+\)', r'crm_time_parse_duration'),
(r'\(crm_time_parse_period@.*\.c:[0-9]+\)', r'crm_time_parse_period'),
(r'\(parse_hms@.*\.c:[0-9]+\)', r'parse_hms'),
(re.escape(cts_cli_data), r'CTS_CLI_DATA'),
(r' default="[^"]*"', r' default=""'),
Expand All @@ -261,6 +260,8 @@ def sanitize_output(s):
(r'last_update time=".*"', r'last_update time=""'),
(r' last-rc-change=[\'"][-+A-Za-z0-9: ]*[\'"],?', r''),
(r'\(parse_date@.*\.c:[0-9]+\)', r'parse_date'),
(r'\(parse_duration_element@.*\.c:[0-9]+\)', r'parse_duration_element'),
(r'\(parse_period@.*\.c:[0-9]+\)', r'parse_period'),
(r'\((pcmk__.*)@.*\.c:[0-9]+\)', r'\1'),
(r'.*Relax-NG validity error : ', r''),
(r'request=".*cibadmin', r'request="cibadmin'),
Expand Down Expand Up @@ -1115,6 +1116,9 @@ class DatesRegressionTest(RegressionTest):
"2019-01-01 00:00:00Z/P", # Duration with no values
"P1Z/2019-02-20 00:00:00Z", # Invalid duration unit
"P1YM/2019-02-20 00:00:00Z", # No number for duration unit
"0000-10-01T00:00:00Z/P1M", # Zero year
"-0001-10-01T00:00:00Z/P1M", # Negative year
"10000-10-01T00:00:00Z/P1M", # Year greater than 9999
]

# Ensure invalid period specifications are rejected
Expand Down
12 changes: 0 additions & 12 deletions include/crm/common/iso8601.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ extern "C" {
*/
typedef struct crm_time_s crm_time_t;

/*!
* \deprecated Use \c crm_time_period_t instead of
* <tt>struct crm_time_period_s</tt>.
*/
typedef struct crm_time_period_s {
crm_time_t *start;
crm_time_t *end;
crm_time_t *diff;
} crm_time_period_t;

/* Creates a new date/time object conforming to ISO 8601, for example:
* Ordinal: 2010-01 12:00:00 +10:00
* Gregorian: 2010-01-01 12:00:00 +10:00
Expand Down Expand Up @@ -82,8 +72,6 @@ char *crm_time_as_string(const crm_time_t *dt, int flags);
crm_time_t *crm_time_parse_duration(const char *duration_str);
crm_time_t *crm_time_calculate_duration(const crm_time_t *dt,
const crm_time_t *value);
crm_time_period_t *crm_time_parse_period(const char *period_str);
void crm_time_free_period(crm_time_period_t *period);

int crm_time_compare(const crm_time_t *a, const crm_time_t *b);

Expand Down
15 changes: 14 additions & 1 deletion include/crm/common/iso8601_compat.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2025 the Pacemaker project contributors
* Copyright 2004-2026 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand Down Expand Up @@ -29,6 +29,13 @@ extern "C" {
* release.
*/

//! \deprecated Do not use
typedef struct crm_time_period_s {
crm_time_t *start;
crm_time_t *end;
crm_time_t *diff;
} crm_time_period_t;

//! \deprecated Do not use
bool crm_time_leapyear(int year);

Expand Down Expand Up @@ -66,6 +73,12 @@ void crm_time_log_alias(int log_level, const char *file, const char *function,
int line, const char *prefix,
const crm_time_t *date_time, int flags);

//! \deprecated Do not use
void crm_time_free_period(crm_time_period_t *period);

//! \deprecated Do not use
crm_time_period_t *crm_time_parse_period(const char *period_str);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions include/crm/common/iso8601_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
extern "C" {
#endif

bool pcmk__time_valid_year(int year);
void pcmk__time_get_ywd(const crm_time_t *dt, uint32_t *y, uint32_t *w,
uint32_t *d);
char *pcmk__time_format_hr(const char *format, const crm_time_t *dt, int usec);
Expand Down Expand Up @@ -63,6 +64,8 @@ struct crm_time_s {
bool duration;
};

bool valid_time(const crm_time_t *dt);

#ifdef __cplusplus
}
#endif
Expand Down
7 changes: 1 addition & 6 deletions lib/common/fuzzers/iso8601_fuzzer.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2024-2025 the Pacemaker project contributors
* Copyright 2024-2026 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand All @@ -21,8 +21,6 @@ int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char *ns = NULL;
crm_time_period_t *period = NULL;

struct timespec tv = { 0, };
crm_time_t *now = NULL;
char *result = NULL;
Expand All @@ -34,9 +32,6 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
ns = pcmk__assert_alloc(size + 1, sizeof(char));
memcpy(ns, data, size);

period = crm_time_parse_period(ns);
crm_time_free_period(period);

qb_util_timespec_from_epoch_get(&tv);
now = pcmk__copy_timet(tv.tv_sec);
result = pcmk__time_format_hr(ns, now,
Expand Down
Loading