Skip to content

Infinite loop when invoking #first #549

@jorgemanrubia

Description

@jorgemanrubia

This enters an infinite loop:

schedule = IceCube::Schedule.new(Time.current) do |schedule|
  schedule.add_recurrence_rule IceCube::IcalParser.rule_from_ical("FREQ=YEARLY;INTERVAL=1;BYMONTHDAY=31;BYMONTH=2")
end
schedule.first(2) # hangs!

We have patched this internally with:

module ValidatedRuleWithInfiniteRecursionGuard
  private
    MAX_LOOPS = 10_000

    def find_acceptable_time_before(boundary)
      count = 0
      until finds_acceptable_time? || count > MAX_LOOPS
        return false if past_closing_time?(boundary)
        count += 1
      end
      true
    end
end

IceCube::ValidatedRule.prepend(ValidatedRuleWithInfiniteRecursionGuard)

I'm happy to submit a fix to the library. It could be the specific patch suggested above, but the several loop and until usages inside the library, combined with the complex logic, looks like a liability. I think a better patch would be to replace the current loop and until usages with safe_ versions that control a max number of iterations to prevent these infinite loops by design. For example:

safe_loop do # m = 10_000 or whatever by default, and can be passed by parameter 
end

What do you think?

Similar to #469

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions