fix(audit L6, L5): DesignLock atomar (INSERT IGNORE, Token, Übernahme per UPDATE, Release nur mit eigenem Token); Farben und Theme-Optionen teilen eine Sperre
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
522fc8ff4d
commit
b59a0c045f
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Support;
|
||||
|
||||
/**
|
||||
* In-memory options table as $GLOBALS['wpdb'] that understands the three statements of DesignLock (INSERT IGNORE,
|
||||
* conditional UPDATE, DELETE by token). $beforeInsert runs before a lock is inserted (a parallel request).
|
||||
*/
|
||||
final class LockTable extends \wpdb
|
||||
{
|
||||
/** @var array<string, string> option_name => option_value */
|
||||
public array $rows = [];
|
||||
|
||||
public ?\Closure $beforeInsert = null;
|
||||
|
||||
public static function install(): self
|
||||
{
|
||||
return $GLOBALS['wpdb'] = new self();
|
||||
}
|
||||
|
||||
public function query($sql)
|
||||
{
|
||||
if (preg_match("/^INSERT IGNORE .* VALUES \('([^']*)', '([^']*)', 'no'\)$/", $sql, $m) === 1) {
|
||||
if ($this->beforeInsert !== null) {
|
||||
($this->beforeInsert)();
|
||||
}
|
||||
if (isset($this->rows[$m[1]])) {
|
||||
return 0;
|
||||
}
|
||||
$this->rows[$m[1]] = $m[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
$update = "/^UPDATE .* SET option_value = '([^']*)' WHERE option_name = '([^']*)' AND option_value = '([^']*)'$/";
|
||||
if (preg_match($update, $sql, $m) === 1) {
|
||||
if (($this->rows[$m[2]] ?? null) !== $m[3]) {
|
||||
return 0;
|
||||
}
|
||||
$this->rows[$m[2]] = $m[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
$delete = "/^DELETE FROM .* WHERE option_name = '([^']*)' AND option_value = '([^']*)'$/";
|
||||
if (preg_match($delete, $sql, $m) === 1 && ($this->rows[$m[1]] ?? null) === $m[2]) {
|
||||
unset($this->rows[$m[1]]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function get_var($sql = null, $x = 0, $y = 0)
|
||||
{
|
||||
preg_match("/option_name = '([^']*)'/", (string) $sql, $m);
|
||||
|
||||
return $this->rows[$m[1]] ?? null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user