Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: validate negative duration strings #120

Closed

Conversation

memdal
Copy link

@memdal memdal commented Nov 14, 2023

A fix to pass validation of negative ISO8601 duration string. As this is allowed in ISO8601 as of 2019.

Related PRs:

@vietj
Copy link
Member

vietj commented Nov 17, 2023

@InfoSec812 what is your opinion about this ?

@InfoSec812
Copy link

The ISO standard does support negative duration using the format in the PR, but I believe the regex used is not quite sufficient to meet the spec. The standard mentions that it is illegal to have a "-" (minus) before a zero ("0") duration, and for completeness it would be good to cover that case. Not sure about how to implement that in regex matching though. Any thoughts?

@pk-work
Copy link
Contributor

pk-work commented Nov 17, 2023

Thanks @InfoSec812 ! Then for me it is fine, to have this PR in. But of course we should have the correct implementation.

@kennethaasan
Copy link

@InfoSec812, I can't find the spec other than behind a paywall. Can you share exactly what it says so that we can implement the same in ajv for the JavaScript world?

@InfoSec812
Copy link

@kennethaasan I had the same problem. The ISO Spec requires that you purchase a copy, but there are pretty good summaries on Wikipedia here: https://en.wikipedia.org/wiki/ISO_8601#Other_Specifications

The summary there says:

It is not permitted to state a zero value time offset with a negative sign, as "−00:00", "−0000", or "−00"

@memdal
Copy link
Author

memdal commented Nov 21, 2023

@InfoSec812 Hi, I've added some test cases and a new regex pattern that does not match a zero duration with a minus sign in front. I tried parsing with java.time.Duration.parse("-PT0S") to check validity, but it allows it (at least for Java 21).

@memdal
Copy link
Author

memdal commented Nov 22, 2023

After rereading https://en.wikipedia.org/wiki/ISO_8601#Other_Specifications. I think disallowed minus signs only apply for UTC offsets such as:
valid: 2023-11-22T02:43:01−07:00
not valid: 2023-11-22T02:43:01−00:00

@InfoSec812
Copy link

Without access to the specification document (behind a paywall), I cannot dispute that and I am willing to accept this interpretation.

@kennethaasan
Copy link

@memdal and I acquired a copy of the ISO 8601-2:2019 spec, and it allows both ways of negative duration:

  • A minus sign before every time component
  • A minus sign as a prefix to the duration designator "P". If there are minus signs before the individual time component when this is used, then the individual time component is reversed

@InfoSec812
Copy link

@memdal and I acquired a copy of the ISO 8601-2:2019 spec, and it allows both ways of negative duration:

* A minus sign before every time component

* A minus sign as a prefix to the duration designator "P". If there are minus signs before the individual time component when this is used, then the individual time component is reversed

@kennethaasan Does the spec say if the duration can have a minus (-) AND be zero?

@memdal
Copy link
Author

memdal commented Nov 29, 2023

I can not seem to find an explicit mention of negative zero durations in the standard. It does however allow for negative individual time scale components.

Excerpts from ISO 8601-2:2019 that allows for negative time scale components:
11.3

11.3.1 General
The following representations are both considered complete representations of duration.

11.3.2 Composite representation
The composite representation of a duration is a more flexible and relaxed specification for duration
than that of ISO 8601-1:2019, 5.5.2. It accepts all expressions of the duration representation given in
ISO 8601-1:2019, 5.5.2 and is given as follows.
[!]["-"]["P"][durationUnits(m)]
where [durationUnits(m)] contains time scale components for expressing (positive or negative)
duration (see 11.2).

11.2

Individual duration units are allowed to have negative values. The following representation denoted as
[durationalUnits(m)] accept negative values per component.
durationUnits(m) = [yearE(m)][monthE(m)][weekE(m)][dayE(m)]["T"][hourE(m)][minuteE(m)][secondE(m)]

11.3.2

When a minus sign is provided as prefix to the duration designator ["P"], the minus sign can be
internalized into individual time scale components within the duration expression by applying to every
time scale component within.

It implies that time scale components are either positive or negative, but seeing as zero values are also allowed in the time scale components (either for zero durations, or to indicate precision), one could argue that both -PT0S and PT-0S are valid forms, as zero is neither positive or negative.

@memdal memdal force-pushed the validate-negative-duration branch 2 times, most recently from 2741ff7 to 9b853e3 Compare January 2, 2024 13:41
Passes validation for duration strings with zero or negative durations.
@memdal memdal force-pushed the validate-negative-duration branch from 9b853e3 to f29b04d Compare January 2, 2024 13:42
@memdal
Copy link
Author

memdal commented Jan 2, 2024

@InfoSec812 I have updated this PR with more testcases for ISO 8601 duration. The change now also allows individual time scale components to be negative.

However I still can not find a mention of the validity of zero time scale components with minus signs in the ISO document, I believe it might not be explicitly mentioned. I believe this PR is now ready for review.

@kennethaasan
Copy link

@InfoSec812 @pk-work, please review/merge. I believe the changes @memdal have done now reflect the spec.

@InfoSec812
Copy link

I do not have merge privileges, but I do approve of the changes.

@pk-work
Copy link
Contributor

pk-work commented Jan 8, 2024

Some test that are looking related to the change are failing. When a fix is provided, I will restart the checks immediately.

@memdal memdal force-pushed the validate-negative-duration branch from b1e9783 to 5bf04d7 Compare January 8, 2024 15:36
Also moved the new duration validation tests to the test-suite-tck.json
file.
@memdal memdal force-pushed the validate-negative-duration branch from 5bf04d7 to 06e4871 Compare January 8, 2024 15:37
@pk-work
Copy link
Contributor

pk-work commented Jan 8, 2024

Tests are passing, but an existing TCK check was changed. @InfoSec812 can you confirm that this change in the TCK is okay? Then I will merge it.

@InfoSec812
Copy link

Tests are passing, but an existing TCK check was changed. @InfoSec812 can you confirm that this change in the TCK is okay? Then I will merge it.

Without access to the ISO specification I have no way to confirm. The JSON Schema specification itself does not define the details of a duration and leaves that to the ISO8601-2

The best I can confirm is the reference in in the RFC draft here: https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-01#section-7.3.1

@InfoSec812
Copy link

There also appears to be a little more detail in RFC3339 - Appendix A: https://www.rfc-editor.org/rfc/rfc3339.html#page-12

@memdal
Copy link
Author

memdal commented Jan 9, 2024

Thanks for the clarification. From the RFC3339 spec I do not think it is built on ISO 8601:2019. So features like fractions, and negative time components should probably not be a thing in a validator for json-schema. I'll close this PR.

@memdal memdal closed this Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants