This is a 12 year old script written in php 5.3 or something which I recently upgraded to 5.6.
It interfaces with paypal parallel payments (grandfathered in) and the bug (not sure how it survived this long) is this:
- User A goes to the payment page
-
$order_id
is generated:mysql_query("select max(order_id)+ 1 as id from orders");
-
$order_id
is inserted into a couple of other tables - User A is redirected to Paypal
Meanwhile
- User B goes to the payment page.
-
$order_id
is the same becauseorders
table hasn't been updated yet
So now whichever users order processes through paypal SECOND and returns success
to the payment script, the INSERT statement will fail because $order_id
has already been inserted into the table.
We are (supposedly) replacing the whole system in a month or two and need a quick fix.
My first thought was:
//source: https://stackoverflow.com/a/3146986/2223106
define('MYSQL_CODE_DUPLICATE_KEY', 1062);
mysql_query($sql);
if (mysql_errno() == MYSQL_CODE_DUPLICATE_KEY) {
$Invoice_id++;
$sql = "INSERT etc
But now I realize maybe I can define a global $order_id
and check it against mysql_query("select max(order_id)+ 1 as id from orders");
, then if it matches the current next-id increment it by one.
Does this seems like a reasonable approach:
$excqry=mysql_query("select max(order_id)+ 1 as id from orders ") or die(mysql_error());
if(mysql_num_rows($excqry) > 0) {
$row1=mysql_fetch_array($excqry);
$Invoice_id = $row1['id'];
if (isset($GLOBALS['order_id']) && ($GLOBALS['order_id'] <= $Invoice_id)){
$GLOBALS['order_id'] = $Invoice_id + 1;
$Invoice_id++;
}
// Continue with our MySQL statements
Obviously this doesn't deal with User C
potentially coming along at the same time, but the site only has a few dozen users a week.