Kontaktovat podporu

Odpovíme e-mailem, obvykle do dvou dnů.

Google reCAPTCHA kontroluje toto odeslání kvůli ochraně před zneužitím; data se přitom předávají společnosti Google. Skript se načte až při otevření tohoto formuláře.

← Všechny články

Kontrola, která platí vždy

Tato služba obsahuje 23 UPDATE příkazů. Právě jeden z nich kontroluje, zda něco změnil. Ta kontrola zní:

'success' => $n->rowCount() >= 0

rowCount() vrací 0, když žádný řádek neodpovídal. Nula je větší nebo rovna nule. Kontrola projde, ať se stane cokoli.

23 příkazů UPDATE, jeden se dívá na výsledek rowCount() >= 0 — projde, i když nic neodpovídalo rowCount() > 0 v celém kódu: 0krát počítadla s řádkem v aktualizované tabulce: 4 z 2 218 dnes nic rozbité není — z důvodu, kterým není tento řádek

K čemu ten příkaz je

Ukládá zaškrtávací políčko: zda majitel počítadla chce týdenní souhrn e-mailem. Adresa je v samostatné tabulce a řádek se tam objeví, teprve když někdo klikne na potvrzovací odkaz v e-mailu, o který požádal. Takový řádek mají čtyři počítadla. Aktivních je 2 218.

U 99,8 % počítadel tedy UPDATE nenajde nic. Koncový bod odpoví success: true a nastavení se neuloží, protože není kam ho uložit.

Komentář nad ním je správný

O tři řádky výš, v téže funkci:

„Jen tam, kde existuje potvrzená zpáteční cesta. Bez ní neexistuje adresa, kam by dopis mohl jít — a zaškrtávací políčko by slibovalo něco, co se nestane.“

To je přesně tak. Někdo o tomto případu přemýšlel, pochopil ho a svou úvahu zapsal. Pak řádek pod ním použil >= tam, kde úvaha vyžadovala >.

Stojí za to se na to podívat zpříma, protože obvyklé vysvětlení — nikoho to nenapadlo — je po ruce a je mylné. Úvaha v souboru je. Selhal jeden znak, na místě, kde špatná a správná verze vypadají na první pohled stejně a chovají se stejně v každém testu, který má řádek k aktualizaci.

Nikdo není klamán

Tady je ta část, kterou by bylo snadné vynechat, a vynechat ji by udělalo tento článek dramatičtějším a méně pravdivým.

Stránka to zaškrtávací políčko nevykreslí, pokud řádek neexistuje. O obrazovku dál, v kódu, který kreslí rámeček nastavení majitele, se nejprve dotazuje tatáž tabulka a celý blok se přeskočí, když se dotaz vrátí prázdný. Majitel počítadla bez potvrzené adresy tedy ovládací prvek nikdy nevidí, nikdy na něj neklikne a nikdy nedostane falešné potvrzení.

Chybná kontrola je dosažitelná jen přímým voláním koncového bodu s platným tokenem. Kdo to udělá, dostane success: true a žádné uložené nastavení. To je skutečná vada, a úzká.

Proč to přesto stojí za zapsání

Funkce je bezpečná díky pojistce, kterou nikdo jako pojistku nezapsal. Řádek, který existuje proto, aby ji učinil bezpečnou, ji bezpečnou nečiní. To, co ano, je podmínka vykreslení v jiné funkci, jejíž komentář vysvětluje, proč je políčko skryté — ne to, že na jeho skrytí něco závisí.

Odstraňte nebo přestavte tu podmínku vykreslení — rozumná věc při předělávání panelu nastavení — a vada se okamžitě projeví, aniž by cokoli kdekoli obě změny spojovalo. Bezpečnost je skutečná, a je náhodná, a náhodná bezpečnost je ten druh, který zmizí při nesouvisející práci.

Tentýž kód to o soubor dál dělá správně. Odpovídající funkce webringu se zeptá, zda řádek existuje, vrátí false, když ne, a aktualizaci vůbec nespustí. Ta tabulka má momentálně nula řádků, takže funkce vrací false při každém volání, což je správná odpověď.

Obecný vzorec

Příkaz UPDATE bez nalezených řádků není chybou v žádné databázi. Je to úspěšný příkaz, který nic neudělal, a každá vrstva nad ním ohlásí úspěch, pokud se někdo nezeptá. Dvacet dva příkazů se tu neptá a u většiny z nich je to v pořádku: aktualizují řádek, o kterém požadavek už prokázal, že existuje.

Ten jediný, který se zeptat potřeboval, se zeptal způsobem, který nemůže selhat. rowCount() >= 0 není slabá kontrola, je to absence kontroly převlečená za kontrolu — a je horší než žádná kontrola, protože další člověk, který funkci čte, vidí, že se výsledek zkoumá, a přestane hledat.

Výraz rowCount() > 0 se v tomto kódu vyskytuje nulakrát. To je číslo, které z překlepu v jednom znaku udělalo něco, co stojí za článek: ne že to bylo jednou napsané špatně, ale že nikde nebyl správný výskyt, se kterým to porovnat.

Opraveno 28. srpna 2026. Koncový bod se teď před aktualizací zeptá, zda řádek existuje, jako to už dělala funkce webringu o soubor dál, a když neexistuje, odpoví false. Zjevná jednoznaková oprava — porovnávat místo toho s větší než nula — byla nejprve změřena a zamítnuta: ovladač hlásí změněné řádky, ne nalezené, takže nastavení políčka na hodnotu, kterou už má, nic nezmění, a tato verze by ohlásila selhání u operace, která byla v pořádku. Obě verze jsou špatně, každá opačným směrem.

Reklama