Open source download manager Fatrat povstal z popela. Autor k dvacetiletému výročí projektu přidal do vínku podporu nejnovější knihovny libtorrent, rozhraní portoval na QT6, došlo k nahrazení podpory java rozšíření pythonem. Webové rozhraní bylo přepsáno s podporou mobilních zařízení. Aplikaci je taktéž možno zkompilovat bez podpory GUI. Více informací v releases.
Zranitelnost Broccoli2Shell (CVE-2026-111497) v kompresní knihovně Brotli se netýká pouze Node.js. Ohroženy jsou také aplikace využívající HTTP. Knihovnu používají webové prohlížeče, servery i řada dalších aplikací a technologií, například také Python nebo Bun. Identifikace všech zranitelných komponent může být obtížná, protože knihovna bývá součástí dalších softwarových balíčků nebo je přímo začleněna do spustitelných souborů aplikací.
Quad9, švýcarský celosvětově působící neziskový poskytovatel DNS, od 24. listopadu 2026 ukončí své služby ve Francii kvůli soudnímu sporu s katarskou televizní stanicí beIN. Ta požadovala blokování domén, které podle ní nelegálně zpřístupňují sportovní přenosy. Francouzský soud Katarům vyhověl a nařídil (🇫🇷, PDF) Quad9 blokaci zavést, pod hrozbou pokuty 1000 eur denně. Provozovatel příkaz odmítá s tím, že blokace
… více »Článek na blogu APNIC vysvětluje, jak správně vytvářet a používat ASPA záznamy — podepsané objekty v RPKI, které uvádějí, kteří poskytovatelé směrování jsou pro dané autonomní číslo (ASN) oprávněni. Síťoví operátoři je mohou využít k ověřování tras BGP a k odhalování úniků tras či podvržených tras.
Byla vydána (𝕏) verze 8.0.0 open source programu pro prolamování hesel hashcat (GitHub, Wikipedie). Přehled novinek v příspěvku v diskusním fóru a pdf.
Byla vydána (𝕏, Bluesky) nová verze 2026.3 linuxové distribuce navržené pro digitální forenzní analýzu a penetrační testování Kali Linux (Wikipedie). Přehled novinek se seznamem 6 nových nástrojů v oficiálním oznámení na blogu.
Výzkumníci ukazují, jak mohou otevřené tunely a IPv6 Extension Headers synchronizovat pakety do krátkých provozních špiček. V kontrolovaném experimentu naměřili přes 180násobnou koncentraci paketového toku vůči průměrné rychlosti odesílání — nikoli 180násobné zvětšení objemu dat. Článek obsahuje metodiku, limity měření i mitigace pro GRE, IPIP a další tunely.
Po velkém úspěchu prvního MobileLinux Hackdaye se vracíme do Českých Budějovic s druhým ročníkem. V pátek 30. října 2026 od 10:00 se v prostorách Jihočeské univerzity uskuteční Embedded & MobileLinux Hackday #2. Těšit se můžete na témata jako Immutable Linux na telefonech (BengalOS), U-Boot a upstream vývoj, AI optimalizace pro embedded systémy nebo otevřený hardware. Nebude chybět praktické hackování, sdílení zkušeností a možnost … více »
Dne 21. října 2026 vydal projekt Node.js bezpečnostní aktualizace opravující deset zranitelností, včetně jedné umožňující potenciální vzdálené spuštění kódu (RCE). Nejzajímavější je CVE-2026-111497, chyba dekodéru Brotli, kterou objevili výzkumníci využívající OpenAI Codex Security. Chyba je v nativním dekodéru Brotli, nikoli v samotném JavaScriptu. Speciálně vytvořený komprimovaný vstup způsobí, že dekodér zamění
… více »Řeším takový návrhový problém a hledám elegantní řešení v C++.
Obecně jde o to, že mám třídu (např. parser), jejíž instance přijímá události (někdo volá její metody), nějak je zpracovává a výsledky předává dál – volá metody jiného objektu (handler). Těch handlerů může být víc, implementují stejné rozhraní a uživatel je registruje před začátkem zpracování pomocí metody addHandler().
Napadá mě několik možností:
addHandler() přidá handler do kolekce a pak budu místo handler->metoda() volat for (auto handler : handlers) handler->metoda() a tím se událost rozešle všem.addHandler() nebude v parseru a parser bude sám schopný pracovat jen s jedním handlerem. Pokud jich bude potřeba víc, vytvoří se proxy handler, který bude implementovat stejné rozhraní a postará se o rozeslání všem stejným způsobem jako v předchozím bodě.Ten handler může mít třeba deset metod, takže se mi to úplně nechce psát všechno ručně, navíc tenhle problém budu asi řešit opakovaně. Časem bych možná chtěl nějak lépe ošetřovat chyby (např. když by jeden handler vyhazoval výjimku, tak aby zpracování dat v ostatních pokračovalo dál a chyba se nějak zpracovala až na konci), ale pro začátek to může být tak, že první vyhozená výjimka zastaví všechno a zpracování skončí.
Přijde mi, že tohle musí být docela obvyklá úloha, snad i návrhový vzor nebo idiom… tak se mi nechce vynalézat kolo. Jak tohle řešíte vy?
P.S. To řešení pomocí maker může vypadat takhle:
#define handler for (auto ___h : handlers) ___h handler->metoda0(); handler->metoda1(a, b); handler->metoda2(a, b, c); ... handler->metoda9(x);
Což tak nějak s minimem úsilí řeší tenhle problém, ale moc nadšený z toho nejsem.
P.P.S. Případně takhle může vypadat kombinace toho makra a proxy:
class XYZContentHandler {
public:
virtual void abc();
virtual void def(int a);
virtual void ghi(int a, int b);
};
class XYZContentHandlerProxy : public XYZContentHandler {
private:
std::vector<std::shared_ptr<XYZContentHandler>> handlers;
public:
void addHandler(std::shared_ptr<XYZContentHandler> handler) {
handlers.push_back(handler);
}
#define handler for (auto ___h : handlers) ___h
void abc() override { handler->abc(); }
void def(int a) override { handler->def(a); }
void ghi(int a, int b) override { handler->ghi(a,b); }
#undef handler
};
Ale nejradši bych se zbavil toho ručně psaného kódu (proxy) a řešil to nějak obecně, genericky.
#include <iostream>
#include <memory>
#include <vector>
using std::vector;
using std::shared_ptr;
using std::make_shared;
using std::cerr;
using std::endl;
using std::forward;
struct ContentHandler {
virtual void handle_a(int x) = 0;
virtual void handle_b(int x, int y) = 0;
virtual void handle_c() = 0;
};
struct Foo: ContentHandler {
virtual void handle_a(int x) { cerr << "Foo::handle_a(" << x << ")" << endl; }
virtual void handle_b(int x, int y) { cerr << "Foo::handle_b(" << x << ", " << y << ")" << endl; }
virtual void handle_c() { cerr << "Foo::handle_c()" << endl; }
};
struct Bar: ContentHandler {
virtual void handle_a(int x) { cerr << "Bar::handle_a(" << x << ")" << endl; }
virtual void handle_b(int x, int y) { cerr << "Bar::handle_b(" << x << ", " << y << ")" << endl; }
virtual void handle_c() { cerr << "Bar::handle_c()" << endl; }
};
template <class R, class T, class ...Args>
void handle_fanout(vector<shared_ptr<T>>& handlers, R (T::*func)(Args...), Args &&... args) {
cerr << "Fanout to " << handlers.size() << " handlers:" << endl;
for (auto& handler : handlers) {
((*handler).*func)(forward<Args>(args)...);
}
}
int main() {
vector<shared_ptr<ContentHandler>> handlers;
handlers.push_back(make_shared<Foo>());
handlers.push_back(make_shared<Bar>());
handle_fanout(handlers, &ContentHandler::handle_a, 3);
handle_fanout(handlers, &ContentHandler::handle_b, 42, 9001);
handle_fanout(handlers, &ContentHandler::handle_c);
}
Je to trochu naprasené... předávání reference na vector by se asi správně mělo nahradit nějakým range nebo po staru párem iterátorů nebo podobně, ale nechtělo se mi to už řešit...
try-catch a chycené výjimky by se někam vykopírovaly pro další zpracování.
Ale ošklivé to asi bude tak jako tak, výjimky jsou zkrátka zlo
Ano, ale otázka je, jak to elegantně implementovat s minimem ručně psaného kódu (proxy) nebo for cyklů rozesetých všude možně. Např. v Javě bych to uměl udělat pomocí reflexe nebo anotací a anotačního procesoru. V jazycích s hygienickými makry si zase dovedu představit elegantní řešení založené na úpravě/generování AST.
Pokud bych omezil počet metod a všechno posílal přes jednu, tak si asi jen ušetřím práci na jednom místě a přidělám práci jinde. Místo prostého volání metod s 0 až N parametry by se musely vytvářet a předávat objekty. Jako API mi to nepřijde moc intuitivní – ten, kdo to bude volat, tak bude řešit otázku, jaké objekty tam může posílat a kde je má vzít (asi v nějaké továrně…) a ten, kdo bude ty události zpracovávat, bude zase řešit otázku, jaké všechny typy mu můžou přijít a jestli to je konečná množina… – místo toho, aby se člověk jednoduše podíval, jaké metody dané rozhraní obsahuje. A když bychom chtěli oddělit API a SPI, tak to bude taky asi horší (tohle zatím neřeším, protože je to jen interní třída, ne nějaké veřejné rozhraní, které by používal a implementoval někdo cizí).
V C++ se tomu zatím nejvíc blíží to Kralykovo řešení, ale taky to není ono – minimálně proto, že psát handle_fanout(handlers, &ContentHandler::handle_a, 3) je výrazně otravnější než psát proxy.handle_a(3) nemluvě o napovídání parametrů v IDE, které si s tím neporadí (ale aspoň kompilátor ty parametry zkontroluje a upozorní na chybu).
class XYZContentHandler {
public:
virtual ~XYZContentHandler() {}
virtual void abc();
virtual void def(int a);
virtual void ghi(int a, int b);
};
class XYZContentHandlerProxy : public XYZContentHandler {
private:
std::vector<std::shared_ptr<XYZContentHandler>> handlers;
public:
void addHandler(std::shared_ptr<XYZContentHandler> handler) {
handlers.push_back(handler);
}
template<typename Func, typename... Args>
void handler_foreach(Func func, Args&&... args)
{
for (auto& h : handlers)
{
try {
(h.get()->*func)(args...); // umyslne bez std::forward, nechceme, aby potom funkce udelala move z argumentu a rozbila tak dalsi handler
}
catch (...) { /* sezer vyjimku */ }
}
}
void abc() override { handler_foreach(&XYZContentHandler::abc); }
void def(int a) override { handler_foreach(&XYZContentHandler::def, a); }
void ghi(int a, int b) override { handler_foreach(&XYZContentHandler::ghi, a, b); }
};
Díky. Nahradil jsem tím to makro a přesunul to do znovupoužitelné třídy ProxyVector.
Pořád mi trochu vadí, že tam musím vyjmenovat všechny ty metody, které se mají přeposílat, ale to asi jinak nejde (bez nějakého generování kódu).
Tiskni
Sdílej: