"recalculate" In Cart Makes Some Items Vanish

The version:

4.1.4, although I’ve seen similar issues with a 3.x release on another site.

The symptoms:

Add a specific item to your cart. (I will explain this more below)

When on the view cart page, change the number of items and press “recalculate”

The item will be thrown out of the cart entirely.

So what specific items will cause this problem?

It seems to be those whose “key” value is negative… when you see them listed on the cart, the fields will be named things like cart_products[-103959546954][amount] If the number is positive, it works fine.

From what I can tell, it seems to involve the following (4.1.4 based description):

It seems that the cart update calls fn_add_product_to_cart. When fn_add_product_to_cart tries to regenerate the cart, it fails to fill in all the details for the entry corresponding to the negative key, so you get, say, “quantity 5, but no product ID” in $cart at the end of fn_add_product_to_cart, which results in the cart “losing” the item.

I’m not sure what would be the best approach to fixing this— possibly "figure out why it’s generating these weird negative “key” values

Further analysis:

The fn_add_to_cart in one case generates tries to assign a value to $id of 2474168827. It gets this from fn_generate_cart_id. When reduced to a 32-bit value, that becomes -1820798469.

When you dump out $cart at the end, the negative number is the key value that has stuck. If I had to guess, there's some sort of issue where we're suffering 32-bit-wraparound related problems.

If you replace line 4010 of fn.cart.php with something like

$cart_id = “P”.md5(implode('
', $_cid));

this should produce a different type of key value, never numeric, and thus unlikely to cause problems.

I've not seen where the cart_id is used for anything other than an index reference. I.e. never a compare or any other operation. Hence, it shouldn't matter whether it's a string, or even a negative number.

But if you think you've found a bug, you should report it in bugtracker and provide a way to reproduce it.