Vlákno názorů k článku Formát EDN: extensible data notation od tzl - Díky za článek. Asi je to tím, že neznám...

  • Článek je starý, nové názory již nelze přidávat.
  • 20. 4. 2021 9:06

    tzl

    Díky za článek.

    Asi je to tím, že neznám closure, ale po přečtení článku k formátu nemám ve formátu (a konverzích) úplně jasno:

    Jak je řešena rovnost klíčů? Je klíč 12 stejný jako 12.0, nebo je to různý klíč? Ztratí se rozdíl mezi :key a "key" v Pythonu už při načtení, nebo tam to ještě lze rozlišit (a je specifikováno co se má stát když tam je oboje, nebo :key dvakrát)?

    Proč je problémem používání normálních symbolů (místo keywords) v EDN formátu to, že mají jhodnotu? Nepředpokládám, že by bylo potřeba je při načítání vyhodnocovat? (V Common Lispu se jako důvod používání uvádí spíše to, že pro keywords není třeba řešit balíky/namespace , a oproti řetězcům mají identitu)

    Jak je to vůbec s namespacy při čtení EDN? Je specifikovaný namespace, ve kterém jsou symboly bez prefixu? Původně jsem četl článek jako že jméno namespace je povinné, ale pak vidím ?monster, takže asi ne. A jak to je s namespacy při konverzi z/do XML (jak v XML, tak v Closure) - jsou mapovány na sebe?

    Jak je to s bezpečností - vypadá to, že read je standardní reader pro Closure. Jsou možnosti jak ho omezit na EDN? Pokud ne, je bezpečné nechat ho číst potenciálně škodlivý vstup?

    Mohl bych to asi všechno postupně sám zkusit, ale to zjistím jen chování, ne specifikaci jak to "má" být.

  • 20. 4. 2021 12:40

    Adam Kalisz
    Stříbrný podporovatel

    Na potenciálně škodlivý vstup by se měl v Clojure (s -> j !) využívat clojure.edn/read-string.

    Myslím, že symboly bez prefixu skončí v namespace :user, jinak si ale typicky data v EDN načítám do nějaké na to myšlené struktury, např. atomu nebo mi to jde jako vstup do funkce/ handleru apod.

    V Clojure je 12 a 12.0 resp. :key a "key" něco jiného, EDN tu sémantiku přenáší. Jak to je při načtení do Pythonu netuším. Možná by si zde mohl člověk pomoct pomocí Hy (takový pseudo-Clojure nad Pythonem), kde tohle jistě řešili.

  • 20. 4. 2021 12:59

    Pavel Tišnovský
    Zlatý podporovatel

    Dobrý den,

    zkusím postupně odpovědět.

    1) klíče 12 a 12.0 jsou podle specifikace odlišné (stejně jako hodnoty prvků, ale tam to pochopitelně není tak viditelné). Příklad příště doplním s info o tom, jak to řeší Python.

    2) :key a "key" se odliší, protože ten první klíč se implicitně uloží ve formě typu (objektu) Keyword:


    {Keyword(key): 'foo',
    'key': 'bar'}

    3) namespaces - výchozí se nepřidává, toto totiž do značné míry závisí na jakyku. Ony se symboly nevyhodnocují při čtení, takže se to (asi?) v praxi ani řešit na úrovni přenosu dat nemusí.

    4) bezpečnost - v Clojure (a tedy i v EDN) se rozlišuje mezi operací "read/read-string" a "eval" s tím, že "eval" se asi nebude na data volat. To by bylo to stejné, jako vyhodnocovat JSON v JavaScriptu evalem - ano někdo to dělá, ale takový člověk si říká o problémy. Zkusím to ukázat na příkladu:


    user=> (require '[clojure.edn :as edn])
    nil


    user=> (read-string "{:key (+ 1 2)}")
    {:key (+ 1 2)}


    user=> (edn/read-string "{:key (+ 1 2)}")
    {:key (+ 1 2)}


    user=> (eval (edn/read-string "{:key (+ 1 2)}"))
    {:key 3}

    Tj..jak read-string tak i edn/read-string sice mapu načtou a převedou do standardní podoby (tedy už se nejedná o řetězec, ale o plnohodnotná data/kód), ale dokud se nezavolá "eval", tak se funkce + nevyhodnotí.

    20. 4. 2021, 13:01 editováno autorem komentáře

  • 20. 4. 2021 20:41

    tzl

    Děkuji oběma za odpověďi, asi je mi to jasnější (a u těch namespaces jsem dalším čtením jinde zjistil, že jsou celkově asi jinak než jsem předpokládal)

    K bezpečnosti čtení - nešlo mi o evaluaci, ale opravdu o čtení - v Common Lispu (omlouvám se, že to mám pořád jako příklad, ale beru to jako známý podobný jazyk) je použití read pro čtení sexpu potenciálně nebezpečné v první řadě protože #., ale i kvůli #+ (umožní detekovat features), kvůli #1= a #1# (riziko různých forem DoS útoků) a dalším. Obdobně "plné" XML umožňuje pomocí entit získávání různých dat nebo DoS ještě předtím, než se obsah začne zpracovávat (XXE). Měl jsem na mysli, zda read v closure deklaruje (i do budoucna) odolnost proti podobným útokům (a A.K. z mého pohledu otázku zodpověděl).