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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions