[Zope3-dev] Potential bug of intid
Tadashi Matsumoto
ma2 at city.plala.jp
Sun Dec 11 04:23:08 EST 2005
Hello
I was looking into the following code of intid's __init__.py.
91 def _generateId(self):
92 """Generate an id which is not yet taken.
93
94 This tries to allocate sequential ids so they fall into the
95 same BTree bucket, and randomizes if it stumbles upon a
96 used one.
97 """
98 while True:
99 if self._v_nextid is None:
100 self._v_nextid = random.randint(0, 2**31)
101 uid = self._v_nextid
102 self._v_nextid += 1
103 if uid not in self.refs:
104 return uid
105 self._v_nextid = None
106
107 def register(self, ob):
108 # Note that we'll still need to keep this proxy removal.
109 ob = removeSecurityProxy(ob)
110 key = IKeyReference(ob)
111
112 if key in self.ids:
113 return self.ids[key]
114 uid = self._generateId()
115 self.refs[uid] = key
116 self.ids[key] = uid
117 return uid
118
2**31 used at the line 100 is a long integer, and there is a possibility
of generating long integer. long interger can not be used with Btree
module.
In fact,
>>> from BTrees import IOBTree
>>> t=IOBTree.IOBTree()
>>> t[2**30] = 'abc'
>>> t[2**31] = 'efg'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: expected integer key
>>>
I think it is better to use, for example, 2**30 instead of 2**31.
By the way, there is a probability (less than 1/2**31 percent) of
generating same intids, if thread switching occurs between the line
114 and 115.
----
Tadashi Matsumoto
ma2 at city.plala.jp
More information about the Zope3-dev
mailing list