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

FixInvalidDayOffsetPreprocessor: Allow DURATION as value #182

Conversation

sunkup
Copy link
Member

@sunkup sunkup commented Oct 31, 2024

Allow DURATION as value in FixInvalidDayOffsetPreprocessor so that it will be found and the actual duration value can be fixed if invalid.

Reported in ICSx5: bitfireAT/icsx5#462

@sunkup sunkup added the bug Something isn't working label Oct 31, 2024
@sunkup sunkup self-assigned this Oct 31, 2024
@sunkup sunkup linked an issue Oct 31, 2024 that may be closed by this pull request
@sunkup sunkup removed the request for review from ArnyminerZ October 31, 2024 13:04
@sunkup sunkup marked this pull request as draft October 31, 2024 13:04
@sunkup sunkup force-pushed the 181-fixinvaliddayoffsetpreprocessor-fails-when-applied-to-the-whole-ical-property-string branch from 2e466f8 to f5e56f6 Compare October 31, 2024 13:06
@sunkup sunkup marked this pull request as ready for review October 31, 2024 13:21
Copy link
Member

@rfc2822 rfc2822 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is based on a real issue? Which one?

Can we require a property (or a list of properties which may have a DURATION) or at least ;VALUE=?

This pre-processor is a very risky and off-the-wall way to fix things and should be used in the most minimal way. For instance, I always fear that some plaintext may contain exactly this content and then be modified …

ArnyminerZ
ArnyminerZ previously approved these changes Nov 4, 2024
Copy link
Member

@ArnyminerZ ArnyminerZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good, makes sense. I didn't know that there was such a property. Should we somehow use it at some point? I mean, we can only fetch new data if necessary knowing that it only updates once a day, for example.

@sunkup
Copy link
Member Author

sunkup commented Nov 4, 2024

I assume this is based on a real issue? Which one?

This one: bitfireAT/icsx5#462
Added to description.

This pre-processor is a very risky and off-the-wall way to fix things and should be used in the most minimal way. For instance, I always fear that some plaintext may contain exactly this content and then be modified …

Yes, that's why I tried to relax the regex as little as possible.

Can we require a property (or a list of properties which may have a DURATION) or at least ;VALUE=?

I will try to narrow it down some more in a sensible way.

@sunkup
Copy link
Member Author

sunkup commented Nov 4, 2024

Updated.

I believe DURATION can only occur as value of the following properties.

RFC 5545

  • DURATION
  • RELATED-TO
  • TRIGGER

RFC 7986

  • REFRESH-INTERVAL

Since TRIGGER never occurs as a value for any of the properties (like DURATION does), it's a bit weird to have it in the regex as well, but I think separating it might make the regex unnecessarily complex.

@sunkup sunkup requested a review from rfc2822 November 4, 2024 11:16
Copy link
Member

@rfc2822 rfc2822 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Working fine.

I have suggestions for method names in tests.

@sunkup sunkup force-pushed the 181-fixinvaliddayoffsetpreprocessor-fails-when-applied-to-the-whole-ical-property-string branch from 3cc4fa6 to e55de0a Compare November 5, 2024 09:31
@sunkup sunkup requested a review from rfc2822 November 6, 2024 14:27
Copy link
Member

@rfc2822 rfc2822 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed the test so that it asserts what is expected (and not what is not expected, which was confusing for me).

And one question :)

Copy link
Member

@rfc2822 rfc2822 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for making this complicated… but I think it's worth to fully understand the details of this regex and class and what they do, otherwise it could make unexpected problems.

@sunkup
Copy link
Member Author

sunkup commented Nov 13, 2024

Sorry for making this complicated… but I think it's worth to fully understand the details of this regex and class and what they do, otherwise it could make unexpected problems.

No worries. I don't like working with regex, but you are totally right. We should not slip up here. I did not fully understand how the non-capturing groups work. I expected them to be excluded from the whole match, but alas they are not and we need to use the list of capturing groups like you say.

I changed the regex to capture only the duration in a capturing group, while ignoring the begining of the string, so problems as with the "CAPTION" scenario should not arise:

"(?:^|^(?:DURATION|REFRESH-INTERVAL|RELATED-TO|TRIGGER);VALUE=)(?:DURATION|TRIGGER):(-?P((T-?\\d+D)|(-?\\d+DT)))$"

I also tried to make the code as explicit as possible with many comments. The first capturing group always contains the whole match. The second match group (match.groupValues[1]) now only contains the actual faulty duration, ie "-PT1D", which is fixed first. Then the whole fixed duration string is replacing the faulty duration string in the whole match string and in the end the whole match string is found and replaced in the original ical.

In the best case we would also add another edge case test for the "CAPTION" scenario. If we are worried about unexpected issues, more tests clamping down on the expected behaviour are always nice to have. I don't see how we can do that though, since "CAPTION" is not a relevant property here as it can not have a duration value.

The alternative would be to drop all the non-capturing groups and simply write a comment about replacing "PT" with "T" in the whole capture.

I also just noticed that match has a match.range and we can directly use it to call replace: s.replace(match.range, fixed). If I understand it correctly, this should replace the actually found occurrence and not run a new search.

AFAIK replace() does not take an int range, so I think we would need to use replaceRange() for that. I don't think we need to use the match range at all though.

@rfc2822
Copy link
Member

rfc2822 commented Nov 13, 2024

To illustrate what I mean: I have now used replaceRange so that we exactly replace the match, so we don't have to find multiple times (with potential different results).

Tests are OK; please have a final look and then I'll merge if it's OK for you.

@sunkup
Copy link
Member Author

sunkup commented Nov 13, 2024

To illustrate what I mean: I have now used replaceRange so that we exactly replace the match, so we don't have to find multiple times (with potential different results).

Tests are OK; please have a final look and then I'll merge if it's OK for you.

Oh, so the match group has a range as well ... Yeah, no. I did not get that from your description. But looks good to me like this. Much shorter 👍

@rfc2822 rfc2822 merged commit d01dba0 into main Nov 13, 2024
8 checks passed
@rfc2822 rfc2822 deleted the 181-fixinvaliddayoffsetpreprocessor-fails-when-applied-to-the-whole-ical-property-string branch November 13, 2024 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FixInvalidDayOffsetPreprocessor fails
3 participants