Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-5198

Calling children_changed? on a deep cyclical data structure will cause semi-infinite looping

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Critical - P2 Critical - P2
    • 7.4.0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Fully Compatible

      I believe the problem is that in the children_changed? method. Internally it will call the _children method which will cause not only immediate children to be returned, but all descendants as well. I believe this is a critical issue as it has the potential to lockup a process doing nonstop looping and cause a denial of service.

      def children_changed?
            _children.any?(&:changed?)
          end
      

      Can be reproduced by the following:

      class Inner
        include Mongoid::Document
      
        embeds_many :friends, :class_name => self.name, :cyclic => true
        embedded_in :parent, :class_name => self.name, :cyclic => true
      
        field :level, :type => Integer
      end
      
      class Outer
        include Mongoid::Document
        embeds_many :inners
      
        field :level, :type => Integer
      end
      
      # create deeply nested record 
      a = Outer.create(level: 0)
      level = 1
      iter = a.inners.create(level: level)
      loop do
        iter.friends.create(level: (level += 1))
        iter = iter.friends[0]
        break if level == 40
      end
      
      # this will never complete
      Outer.first.changed?
      

       

            Assignee:
            oleg.pudeyev@mongodb.com Oleg Pudeyev (Inactive)
            Reporter:
            eugegim@gmail.com Eugene Gimelberg
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: