2017-04-24 35 views
0

下面是一些代碼(具有相關聯的數據),用於計數東西流星應用的本質。計數可以連接在一起,這樣一是可以增加另:流星 - 檢測無限循環

// The counting and linking code. 
Meteor.methods({ 
    'counts.increment'(countId) { 
     const count = Counts.findOne(countId); 
     Counts.update(countId,{ $inc: { count: 1 } }) 
     Meteor.call('counts.check-links',count._id); 
    }, 
    'counts.check-links'(countId){ 
     var count = Counts.findOne(countId); 
     count.links.forEach(function (linkId) { 
      updated = false; 
      const link = Links.findOne(linkId); 
      const primary = Counts.findOne(link.primary); 
      const secondary = Counts.findOne(link.secondary); 
      if (primary.count == link.level) { 
       updated = true; 
       Counts.update(secondary._id, {$inc: {count: 1}}); 
      } 
      if (updated) { 
       Meteor.call('counts.check-links',secondary._id); 
      } 
     }) 
    } 
}) 

// Some data... 
Count: { 
    _id: 1, 
    value: 0, 
    name: A, 
    links: [3] 
} 

Count: { 
    _id: 2, 
    value: 0, 
    name: B, 
    links: [4] 
} 

Link: { 
    _id: 3, 
    primary: 1, 
    secondary: 2 
} 

Link: { 
    _id: 4, 
    primary: 2, 
    secondary: 1 
} 

所以,每個計數鏈接到其他如果Meteor.call('projects.increment',1)稱爲該代碼會崩潰。檢測這樣的設置可以是相當困難的,因爲有可能是計數的非常複雜的安排和鏈接也可以減少,置零,操作每隔N計數&℃。 & c。不過,爲了提出這個問題並不重要。我認爲

一種可能性是添加內counts.check-links一個計數器,該計數器將環路的任意數量後停止執行,例如5.假定爲防止篡改,這個計數器的值必須存儲在數據庫中並通過Meteor方法執行。它將需要在任何check-links調用序列結束時重置。

我不知道這是否是最好的辦法,或者如果這樣怎麼可能是一個很好的方式來實現它,所以我很想知道,如果任何人有任何建議。

+1

確保驗證您的服務器方法或其超級假冒此方法調用或做一些nosql注入。 – Dude

+0

服務器只將數據發佈屬於已登錄的用戶,並且該方法調用也檢查正在對數據執行的操作的登錄用戶擁有,因此應該有希望覆蓋它。 – knirirr

+0

我應該補充說,在實際的應用程序中還有一個Meteor.method參數的檢查 - 我從這裏的例子中省略了這種事情。 – knirirr

回答

1

您可以創建一組已訪問過的所有對象(「計數」)的;所以如果你按照這樣一個對象的鏈接,你可以避免再次處理它,從而進入無限遞歸。

編輯:例子 我對流星不熟悉,所以請原諒它是否不能像預期的那樣工作......這是所有允許指向對象引用的編程語言的常見問題,該解決方案遵循類似的模式。

// The counting and linking code. 
Meteor.methods({ 
    ... 
'counts.check-links'(countId, alreadyVisited){ 

    if (!alreadyVisited) alreadyVisited = {}; 
    if (alreadyVisited[countId]) return; 
    alreadyVisited[countId] = true; 

    var count = Counts.findOne(countId); 
    count.links.forEach(function (linkId) { 
     updated = false; 
     const link = Links.findOne(linkId); 
     const primary = Counts.findOne(link.primary); 
     const secondary = Counts.findOne(link.secondary); 
     if (primary.count == link.level) { 
      updated = true; 
      Counts.update(secondary._id, {$inc: {count: 1}}); 
     } 
     if (updated) { 
      Meteor.call('counts.check-links',secondary._id, alreadyVisited); 
     } 
    }) 
} 
+0

謝謝,我會放棄。大概一個人應該清空已經在最後的else塊中,因爲如果沒有更新,那麼就沒有必要檢查更多的鏈接。 – knirirr

+0

看起來像這樣做。爲了安全起見,我沒有在方法中創建已存在的方法,而是將其存儲在數據庫中,以便我可以應用一些檢查(例如登錄用戶)。否則,我已經使用了你放在那裏的東西。 – knirirr