From the book "Redis in Action" that I read, I saw the following example, and now I wonder if this is correct or not. The example contains the following code in python:
def purchase_item(conn, buyerid, itemid, sellerid, lprice):
buyer = "users:%s"%buyerid
seller = "users:%s"%sellerid
item = "%s.%s"%(itemid, sellerid)
inventory = "inventory:%s"%buyerid
end = time.time() + 10
pipe = conn.pipeline()
while time.time() < end:
try:
pipe.watch("market:", buyer)
price = pipe.zscore("market:", item)
funds = int(pipe.hget(buyer, "funds"))
if price != lprice or price > funds:
pipe.unwatch()
return None
pipe.multi()
pipe.hincrby(seller, "funds", int(price))
pipe.hincrby(buyer, "funds", int(-price))
pipe.sadd(inventory, itemid)
pipe.zrem("market:", item)
pipe.execute()
return True
except redis.exceptions.WatchError:
pass
return False
As you can see, this example uses pipelining and from what I understand, the commands are not executed until pipe.execute () is called. In this example, you see the if statement in #B, but is this the price value returned here? Or, an exploit of the code is invoked somehow buffered when conn.pipeline () is called.
source
share