From b459551ccbe9efdeab2533dbd4b2cd502cd1c297 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Thu, 28 Nov 2024 16:01:24 +0100 Subject: [PATCH] anti-bot.php: use transactions --- inc/anti-bot.php | 82 ++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/inc/anti-bot.php b/inc/anti-bot.php index f21b6d5f..e9fedc75 100644 --- a/inc/anti-bot.php +++ b/inc/anti-bot.php @@ -190,55 +190,63 @@ class AntiBot { } } -function _create_antibot($board, $thread) { +function _create_antibot($pdo, $board, $thread) { global $config, $purged_old_antispam; $antibot = new AntiBot(array($board, $thread)); - // Delete old expired antispam, skipping those with NULL expiration timestamps (infinite lifetime). - if (!isset($purged_old_antispam) && $config['auto_maintenance']) { - $purged_old_antispam = true; - purge_old_antispam(); - } - - retry_on_deadlock(4, function() use($thread, $board, $config) { - // Keep the now invalid timestamps around for a bit to enable users to post if they're still on an old version of - // the HTML page. - // By virtue of existing, we know that we're making a new version of the page, and the user from now on may just reload. - if ($thread) { - $query = prepare('UPDATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` = :thread AND `expires` IS NULL'); - } else { - $query = prepare('UPDATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` IS NULL AND `expires` IS NULL'); - } - - $query->bindValue(':board', $board); - if ($thread) { - $query->bindValue(':thread', $thread); - } - $query->bindValue(':expires', $config['spam']['hidden_inputs_expire']); - // Throws on error. - $query->execute(); - }); - try { - $hash = $antibot->hash(); + $pdo->beginTransaction(); + + // Delete old expired antispam, skipping those with NULL expiration timestamps (infinite lifetime). + if (!isset($purged_old_antispam) && $config['auto_maintenance']) { + $purged_old_antispam = true; + purge_old_antispam(); + } + + retry_on_deadlock(4, function() use($config, $board, $thread) { + // Keep the now invalid timestamps around for a bit to enable users to post if they're still on an old version of + // the HTML page. + // By virtue of existing, we know that we're making a new version of the page, and the user from now on may just reload. + if ($thread) { + $query = prepare('UPDATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` = :thread AND `expires` IS NULL'); + } else { + $query = prepare('UPDATE ``antispam`` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE `board` = :board AND `thread` IS NULL AND `expires` IS NULL'); + } - retry_on_deadlock(2, function() use($board, $thread, $hash) { - // Insert an antispam with infinite life as the HTML page of a thread might last well beyond the expiry date. - $query = prepare('INSERT INTO ``antispam`` VALUES (:board, :thread, :hash, UNIX_TIMESTAMP(), NULL, 0)'); $query->bindValue(':board', $board); - $query->bindValue(':thread', $thread); - $query->bindValue(':hash', $hash); + if ($thread) { + $query->bindValue(':thread', $thread); + } + $query->bindValue(':expires', $config['spam']['hidden_inputs_expire']); // Throws on error. $query->execute(); }); - } catch(\PDOException $e) { - if ($e->errorInfo === null || $e->errorInfo[1] != MYSQL_ER_LOCK_DEADLOCK) { - throw $e; - } else { - error_log('Multiple deadlocks on _create_antibot while inserting, skipping'); + + try { + $hash = $antibot->hash(); + + retry_on_deadlock(2, function() use($board, $thread, $hash) { + // Insert an antispam with infinite life as the HTML page of a thread might last well beyond the expiry date. + $query = prepare('INSERT INTO ``antispam`` VALUES (:board, :thread, :hash, UNIX_TIMESTAMP(), NULL, 0)'); + $query->bindValue(':board', $board); + $query->bindValue(':thread', $thread); + $query->bindValue(':hash', $hash); + // Throws on error. + $query->execute(); + }); + } catch(\PDOException $e) { + if ($e->errorInfo === null || $e->errorInfo[1] != MYSQL_ER_LOCK_DEADLOCK) { + throw $e; + } else { + error_log('Multiple deadlocks on _create_antibot while inserting, skipping'); + } } + } catch (\PDOException $e) { + $pdo->rollBack(); + throw $e; } + $pdo->commit(); return $antibot; }