Cosa fanno i convertitori di sintassi
JSON, YAML, XML, TOML e CSV non contengono le stesse cose. Questa pagina indica esattamente come viene mappata ciascuna forma, quali conversioni sono con perdita di dati e cosa lo strumento si rifiuta di fare.
Cosa converte
Nove conversioni dirette: JSON in YAML, YAML in JSON, JSON in XML, XML in JSON, JSON in TOML, TOML a JSON, YAML a TOML, TOML a YAML e JSON a CSV. Tutti vengono eseguiti nella scheda del browser; non viene caricato nulla.
Ogni conversione funziona allo stesso modo internamente: il documento di origine viene letto in un valore JavaScript ordinario e quel valore viene scritto nel formato di destinazione. Da YAML a TOML non è un caso speciale, è il lettore YAML seguito dallo scrittore TOML. Questo è il motivo per cui le avvertenze di seguito sono indicate per formato anziché per coppia: un avvertimento sulle date e orari di TOML si applica ovunque appaia TOML.
CSV è di sola scrittura e lo è deliberatamente. Leggere CSV significa indovinare un delimitatore, un dialetto di virgolette, se la prima riga è un'intestazione e un tipo per ogni cella: quattro tentativi, ognuno dei quali un convertitore sbaglia silenziosamente. Questo è un lavoro per uno strumento che chiede.
XML: attributi, array e regole che abbiamo scelto
XML non ha una mappatura canonica JSON, quindi è stato necessario scegliere le convenzioni. Sono visibili sullo schermo ogni volta che XML è uno dei due formati e sono questi.
Gli attributi diventano chiavi oggetto con il prefisso @. <user id="7"><name>Ada</name></user> si legge come {"utente":{"@id":"7","name":"Ada"}}. Il prefisso è ciò che impedisce a un attributo e a un elemento figlio con lo stesso nome di collassare in un'unica chiave: <user id="7"><id>other</id></user> li mantiene entrambi.
Il testo all'interno di un elemento che ha anche attributi o elementi figlio risiede sotto la chiave #text. Un elemento che non contiene altro che testo si riduce a quel testo. Una sezione CDATA risiede sotto #cdata, quindi i suoi contenuti sono visibilmente dati anziché markup.
Gli elementi fratelli ripetuti diventano un array. Un nome di elemento che appare una volta non diventa un array: XML non fornisce al parser alcun modo per distinguere "un elenco con un elemento" da "un singolo valore" e nessun convertitore può inventare tale informazione. Se hai bisogno di una forma stabile, questo è un argomento a favore di uno schema, non per un convertitore più intelligente.
I prefissi dello spazio dei nomi vengono mantenuti alla lettera: <ns:item> è la chiave ns:item e xmlns:ns è l'attributo @xmlns:ns. Niente viene risolto, riscritto o eliminato, perché risolvere un prefisso butta via il testo che il documento effettivamente conteneva.
Un tag a chiusura automatica viene letto come una stringa vuota. La dichiarazione XML, le istruzioni di elaborazione e i commenti vengono eliminati. Andando al contrario, lo strumento scrive la propria dichiarazione e mai un DOCTYPE.
La scrittura di XML, una chiave che non è un nome di elemento XML legale (una con uno spazio, una che inizia con una cifra, una che inizia con le lettere xml) viene rifiutata per nome anziché riscritta silenziosamente. Un elemento rinominato silenziosamente produce un documento che non convalida nulla.
Le entità esterne vengono rifiutate, non semplicemente disabilitate
Un documento XML può dichiarare entità in un DOCTYPE. Un parser che li espande è la vulnerabilità XXE: un'entità dichiarata SYSTEM "file:///etc/passwd" legge un file locale, una che punta a URL effettua una richiesta controllata da un utente malintenzionato e una catena di entità interne è il "miliardo di risate" Denial of Service che trasforma poche centinaia di byte in gigabyte.
Questo convertitore non configura un parser per fare attenzione ai DOCTYPE. Rifiuta qualsiasi documento che ne contenga uno, prima che al parser venga assegnato un singolo byte, senza alcuna opzione per disattivare il rifiuto. Ciò rende la garanzia una proprietà del nostro codice piuttosto che un'impostazione predefinita di una dipendenza - e la differenza è importante, perché le impostazioni predefinite cambiano tra le versioni e il nostro stesso rifiuto è coperto da test che lo alimentano con ogni payload standard XXE e affermano che nulla è stato recuperato e nulla è stato espanso.
Il costo pratico: un documento con DOCTYPE non verrà convertito qui anche se è innocuo. Elimina DOCTYPE se il contenuto è tuo.
I datetime TOML non hanno equivalenti da nessun'altra parte
TOML 1.0 ha quattro tipi temporali e JSON, YAML e XML non ne hanno nessuno: offset data-ora (1979-05-27T07:32:00Z), data-ora locale (1979-05-27T07:32:00, senza zona, volutamente), data locale (1979-05-27) e ora locale (07:32:00).
Ciascuno diventa la stringa RFC 3339 esattamente come è stata scritta e la conversione ti dice a quali valori lo ha fatto e a quale dei quattro tipi apparteneva ciascuno. L’alternativa – emettere un singolo istante UTC per tutti e quattro – sposterebbe l’ora locale in una zona che il documento si rifiuta esplicitamente di indicare, il che è una risposta sbagliata piuttosto che una risposta perdente.
La conversione indietro produce stringhe tra virgolette, non datetime. Un viaggio di andata e ritorno da TOML a JSON a TOML modifica pertanto i tipi di tali valori. Non c’è modo di aggirare questo problema senza inventare una convenzione che lo strumento ricevente dovrebbe condividere, e inventarne una silenziosamente sarebbe peggio.
TOML gli interi sono firmati 64-bit; I numeri JSON sono IEEE-754 doppi. Un intero passato 2^53 - 1 diventa una stringa, con il percorso indicato in un avviso, anziché perdere le ultime cifre a causa di un arrotondamento che non noteresti.
TOML non ha null. Una chiave nulla viene omessa dall'output e denominata in un avviso; un null all'interno di un array diventa una stringa vuota, perché rimuovendolo si sposterebbe ogni indice successivo. La radice di un documento TOML è sempre una tabella, quindi un array o un semplice valore nella radice viene rifiutato con una frase che ne spiega il motivo.
YAML: ancore, torrenti e il problema Norvegia
YAML viene letto con uno schema ristretto che può produrre solo stringhe, numeri, booleani, null, elenchi e mappe. I tag che costruiscono oggetti arbitrari - !!js/function, !!python/object/apply, !!binary - vengono rifiutati, che è l'intera ragione per cui esiste la restrizione: un caricatore che li onora è un costruttore di oggetti arbitrari che indossa i panni di un file di configurazione.
Ancore e alias vengono risolti in dati ripetuti. Un documento che si espande oltre un milione di valori una volta seguiti i suoi alias viene rifiutato anziché consentire di congelare la scheda; un alias ricorsivo viene rifiutato completamente, perché nessun altro formato qui può esprimere un ciclo.
Un flusso di diversi documenti separati da --- diventa un array di documenti e la conversione lo dice. Nessun altro formato in questo strumento dispone di un flusso, quindi un array è l'unica mappatura onesta.
YAML vieta una chiave di mappatura ripetuta e ogni parser ne gestisce una in modo diverso. Questo strumento mantiene l'ultimo valore (utilizzato dalla regola JSON.parse) e ti dice che è successo, con la posizione della ripetizione. Scartare silenziosamente un documento sarebbe peggio; scegliere silenziosamente un valore senza dirlo sarebbe ancora peggio.
Il problema della Norvegia: in YAML 1.1, gli scalari senza virgolette y, sì, on, no, off e il codice paese NO si risolvono tutti in booleani, ovvero come un elenco di codici paese si trasforma in un elenco di veri e falsi. Questo strumento legge YAML 1.2, dove solo vero e falso sono booleani, quindi NO rimane la stringa NO. Quando scrive YAML cita ogni stringa che un parser 1.1 potrebbe leggere erroneamente — 'NO', 'yes', 'on', '1.0', '0755', '2001-12-14' — in modo che l'output sia sicuro da inviare a uno strumento che non è stato spostato in 1.2. Ciò costa alcuni caratteri di virgoletta e acquista la correttezza.
Le stringhe che assomigliano a numeri mantengono le virgolette per lo stesso motivo: "0755" rimane una stringa anziché diventare 755 e "1.0" rimane una stringa anziché diventare 1.
I commenti si perdono in ogni direzione. JSON, CSV e gli altri non hanno un posto dove metterli e non c'è modo di indovinare dove dovrebbero andare al ritorno.
da JSON a CSV: appiattimento e apostrofo che interrompe una formula
Un array diventa le righe, un record per elemento. Un oggetto la cui singola proprietà contiene un array utilizza quell'array come righe, perché {"users": [ ... ]} è in gran parte una tabella con un'etichetta - e la conversione dice ad alta voce che lo ha fatto. Qualsiasi altro oggetto è una singola riga. Una stringa semplice, un numero o un valore nullo vengono rifiutati: un rettangolo necessita di record.
Gli oggetti e gli array nidificati vengono appiattiti in nomi di colonne punteggiate, con un punto sia per le chiavi degli oggetti che per gli indici degli array: address.city, tags.0, tags.1. Un separatore, una regola. Una chiave che contiene già un punto rende ambiguo il nome della colonna con un percorso nidificato; lo strumento avvisa invece di inventare uno schema di fuga che nessun foglio di calcolo capirebbe.
Le chiavi sono unite su ogni riga, nell'ordine in cui sono state visualizzate per prime. Una riga in cui manca un campo ottiene una cella vuota anziché una colonna spostata e la conversione avvisa che le righe erano irregolari. Un oggetto vuoto o un array vuoto diventa una cella vuota sotto il proprio percorso anziché svanire.
Segue la virgolettatura RFC 4180: un campo contenente il delimitatore, una virgoletta doppia, CR o LF è racchiuso tra virgolette doppie e una virgoletta incorporata viene scritta due volte. I record sono separati da CRLF. Anche i campi con spazi bianchi iniziali o finali vengono citati, perché altrimenti i fogli di calcolo li ritagliano silenziosamente. Unicode passa senza modifiche e un segno di ordine dei byte può essere preceduto per i fogli di calcolo che ne necessitano per leggere UTF-8.
La formula iniettabile è quella che morde. Una cella che inizia con =, +, -, @, una tabulazione o un ritorno a capo viene eseguita come formula da Excel, LibreOffice Calc e Fogli Google nel momento in cui il file viene aperto. =cmd|'/c calc'!A1 è la dimostrazione che tutti citano; =IMPORTXML(...) è quello che manda silenziosamente il foglio da qualche parte. Un convertitore che scrive una stringa di questo tipo alla lettera ha trasformato i tuoi dati nell'esecuzione del codice di qualcun altro, in un file che sembra inerte.
Quindi una cella di testo che inizia con uno di questi caratteri è preceduta da un apostrofo, che ogni foglio di calcolo principale legge come "questo è testo" e non viene mostrato nella cella. I numeri vengono lasciati soli: un numero -5 è un numero, non una formula. Viene riportato il conteggio delle celle sfuggite e l'evasione può essere disattivata, nel qual caso lo strumento dice chiaramente cosa hai appena disattivato.
CSV non può distinguere una stringa vuota da una stringa nulla. Entrambi diventano una cella vuota e la conversione conta i valori nulli, quindi sai che è successo.
Limiti e cosa succede quando ne raggiungi uno
Ogni formato ha un limite di caratteri, applicato prima ancora che un parser venga scaricato: 8 milioni per JSON, 4 milioni per XML e per a CSV fonte, 2 milioni per YAML E TOML. Oltre a ciò, lo strumento rifiuta con il numero esatto, anziché diventare una scheda che non risponde e perde ciò che hai incollato.
L'output di CSV è inoltre limitato a 100,000 righe e 2,000 colonne, poiché un array profondamente nidificato si appiattisce in una colonna per elemento e alcuni megabyte di JSON possono diventare una tabella che nessun foglio di calcolo aprirà.
L'input vuoto e contenente solo spazi viene segnalato come vuoto anziché convertito in un documento nullo o vuoto. La sintassi non valida viene segnalata con una riga e una colonna in tutti e quattro i formati leggibili.
I parser stessi vengono scaricati solo quando una conversione li richiede. L'apertura del toolkit per decodificare un JWT non ne recupera nessuno.
Cosa succede a ciò che incolli
- Ogni conversione, hash, decodifica e differenza viene eseguita nella scheda del tuo browser. Nessun input viene caricato, registrato o archiviato su un server, perché non è coinvolto alcun server una volta caricata la pagina.
- Gli hash provengono dall'implementazione Web Crypto del browser e gli UUID dal suo generatore casuale crittograficamente sicuro. Nessuno dei due prevede una chiamata di rete.
- Niente di ciò che digiti viene scritto nella memoria locale o in un cookie. Ricaricando la pagina la si elimina; chiudendo la scheda la si elimina.
- L'analisi a livello di sito viene eseguita solo sull'host di produzione canonico configurato e viene divulgata nell'Informativa sulla privacy; gli host locali e di anteprima lo rifiutano. Valori, token, URL e contenuti dei file incollati sono esclusi dagli eventi di analisi di ToolAcre. La pubblicità è disabilitata nella configurazione attuale.
- Detto questo: una chiave JWT o API è una credenziale attiva. L'abitudine più sicura è non incollarne mai uno in una pagina web che non hai scritto tu, per quanto attendibili siano le sue affermazioni, inclusa questa.
Domande
Perché il mio documento XML fallisce con "dichiara un DOCTYPE"?
Perché contiene una dichiarazione del tipo di documento e questo convertitore le rifiuta tutte anziché fidarsi dell'impostazione del parser per gestire le entità in modo sicuro. Elimina DOCTYPE se il contenuto è tuo. Non esiste alcuna opzione per consentirlo.
Perché il mio TOML datetime è tornato come una stringa tra virgolette?
Perché JSON, YAML e XML non hanno un tipo di data. Il valore data/ora è stato convertito nel testo RFC 3339 con cui è stato scritto, ovvero una stringa in ogni altro formato. La riconversione produce quindi una stringa e lo strumento ti avvisa nel momento in cui accade anziché lasciarti scoprire in seguito.
Perché una delle mie celle CSV inizia con un apostrofo?
Perché il suo testo inizia con =, +, -, @, una tabulazione o un ritorno a capo e un foglio di calcolo esegue tale cella come formula quando il file viene aperto. L'apostrofo contrassegna la cella come testo; non fa parte del valore una volta letta la cella. Puoi disattivare la fuga e lo strumento ti dirà cosa significa.
Perché un singolo elemento XML ripetuto non è un array?
Perché XML non fornisce alcun modo per distinguere un elenco di uno da un singolo valore. Entrambi sono scritti in modo identico. Fare un'ipotesi in entrambe le direzioni sarebbe sbagliato la metà delle volte, quindi lo strumento segnala cosa c'è effettivamente.
Posso riconvertire CSV in JSON qui?
No. Per leggere CSV correttamente è necessario decidere un delimitatore, un dialetto per le virgolette, se la prima riga è un'intestazione e un tipo per ogni cella. Un convertitore che indovina tutti e quattro gli errori in silenzio, il che è il modo peggiore per sbagliare. Utilizza uno strumento CSV che lo richieda.
Perché "NO" non viene convertito in falso?
Perché quel comportamento appartiene a YAML 1.1 e questo strumento legge YAML 1.2, dove solo vero e falso sono booleani. Il comportamento 1.1 è il motivo per cui il codice paese della Norvegia è uno scherzo ricorrente nella gestione della configurazione. Quando lo strumento scrive YAML cita tali stringhe in modo che nessun parser 1.1 a valle possa leggerle erroneamente.
Limitazioni
- CSV è scritto, mai letto. Per scelta, qui non è prevista la conversione da CSV a JSON.
- I commenti si perdono in ogni direzione, in ogni formato che li abbia.
- Una data/ora TOML diventa una stringa in ogni altro formato, quindi un viaggio di andata e ritorno TOML modifica questi tipi. Non esiste un percorso senza perdite.
- Un documento XML contenente un DOCTYPE viene rifiutato completamente, compresi quelli innocui, e il rifiuto non può essere disattivato.
- Un singolo elemento XML ripetuto non può essere distinto da uno non ripetuto, quindi da XML a JSON a XML non sempre restituisce la forma originale.
- XML contenuto misto - testo intercalato con elementi secondari - perde la posizione del testo rispetto agli elementi secondari e non può andare avanti e indietro.
- I valori XML sono stringhe a meno che non sia attivata l'inferenza del tipo, perché XML non dichiara alcun tipo; con deduzione su, "0755" e "NO" sono soggetti ai soliti fraintendimenti.
- TOML non ha null: le chiavi null vengono eliminate dall'output TOML e i null all'interno degli array diventano stringhe vuote.
- La radice di un documento TOML deve essere una tabella, quindi un array o uno scalare JSON non può essere convertito in TOML.
- I numeri JSON sono IEEE-754 doppi. Gli interi successivi a 2^53 vengono convertiti in stringhe anziché arrotondati silenziosamente, modificandone il tipo.
- CSV non riesce a distinguere una stringa vuota da una stringa nulla; entrambi sono scritti come una cella vuota.
- L'appiattimento CSV utilizza un punto sia per le chiavi degli oggetti che per gli indici dell'array, quindi una chiave che contiene già un punto produce un nome di colonna ambiguo di cui viene visualizzato un avviso ma senza escape.
- YAML ancore e alias vengono risolti anziché conservati; l'output non ha ancoraggi e un alias ricorsivo viene rifiutato perché nessun formato di destinazione può esprimere un ciclo.
- L'input è limitato per formato: 8 milioni di caratteri per JSON, 4 milioni per XML, 2 milioni per YAML e TOML - e i documenti di grandi dimensioni vengono rifiutati anziché elaborati lentamente.
- Niente qui convalida rispetto a uno schema. Un documento può essere convertito in modo pulito e tuttavia essere sbagliato per il suo scopo.