Português (Brasil)

O que os conversores de sintaxe fazem

JSON, YAML, XML, TOML e CSV não possuem as mesmas coisas. Esta página indica exatamente como cada forma é mapeada, quais conversões apresentam perdas e o que a ferramenta se recusa a fazer.

O que converte

Nove conversões direcionadas: JSON para YAML, YAML para JSON, JSON para XML, XML para JSON, JSON para TOML, TOML para JSON, YAML para TOML, TOML para YAML e JSON para CSV. Cada um é executado na guia do seu navegador; nada é carregado.

Cada conversão funciona da mesma maneira internamente: o documento de origem é lido em um valor JavaScript comum e esse valor é gravado no formato de destino. YAML para TOML não é um caso especial, é o leitor YAML seguido pelo escritor TOML. É por isso que as advertências abaixo são declaradas por formato e não por par - uma advertência sobre TOML data e hora se aplica onde quer que TOML apareça.

CSV é somente gravação e deliberadamente. Ler CSV significa adivinhar um delimitador, um dialeto de citação, se a primeira linha é um cabeçalho e um tipo para cada célula - quatro tentativas, cada uma das quais um conversor erra silenciosamente. Esse é um trabalho para uma ferramenta que pergunta.

XML: atributos, arrays e as regras que escolhemos

XML não possui mapeamento canônico JSON, então as convenções tiveram que ser escolhidas. Eles ficam visíveis na tela sempre que XML for um dos dois formatos, e são estes.

Os atributos tornam-se chaves de objeto prefixadas com @. <user id="7"><name>Ada</name></user> lê como {"user":{"@id":"7","name":"Ada"}}. O prefixo é o que impede que um atributo e um elemento filho com o mesmo nome se reúnam em uma chave - <user id="7"><id>other</id></user> mantém ambos.

O texto dentro de um elemento que também possui atributos ou elementos filhos reside na chave #text. Um elemento que contém nada além de texto é recolhido para esse texto. Uma seção CDATA reside em #cdata, portanto seu conteúdo é visivelmente dados em vez de marcação.

Elementos irmãos repetidos tornam-se um array. Um nome de elemento que aparece uma vez não se torna um array - XML não dá ao analisador nenhuma maneira de diferenciar "uma lista com um item" de "um único valor", e nenhum conversor pode inventar essa informação. Se você precisa de uma forma estável, isso é um argumento a favor de um esquema, não de um conversor mais inteligente.

Os prefixos de namespace são mantidos literalmente: <ns:item> é a chave ns:item e xmlns:ns é o atributo @xmlns:ns. Nada é resolvido, reescrito ou eliminado, porque a resolução de um prefixo joga fora o texto que o documento realmente continha.

Uma tag de fechamento automático é lida como uma string vazia. A declaração XML, as instruções de processamento e os comentários são eliminados. Indo para o outro lado, a ferramenta escreve sua própria declaração e nunca um DOCTYPE.

Escrever XML, uma chave que não é um nome de elemento XML legal - uma com um espaço, uma começando com um dígito, uma começando com as letras xml - é recusada pelo nome em vez de reescrita silenciosamente. Um elemento renomeado silenciosamente produz um documento que não é validado por nada.

Entidades externas são recusadas, e não apenas desativadas

Um documento XML pode declarar entidades em um DOCTYPE. Um analisador que os expande é a vulnerabilidade XXE: uma entidade declarada SYSTEM "file:///etc/passwd" lê um arquivo local, uma que aponta para um URL faz uma solicitação que um invasor controla e uma cadeia de entidades internas é a negação de serviço de "bilhões de risadas" que transforma algumas centenas de bytes em gigabytes.

Este conversor não configura um analisador para ter cuidado com DOCTYPEs. Ele recusa qualquer documento que contenha um, antes que o analisador receba um único byte, sem opção de desativar a recusa. Isso torna a garantia uma propriedade do nosso código, e não da configuração padrão de uma dependência - e a diferença é importante, porque os padrões mudam entre as versões e nossa própria recusa é coberta por testes que alimentam cada carga útil XXE padrão e afirmam que nada foi buscado e nada foi expandido.

O custo prático: um documento com DOCTYPE não será convertido aqui, mesmo quando for inofensivo. Exclua DOCTYPE se o conteúdo for seu.

TOML datetimes não têm equivalente em nenhum outro lugar

TOML 1.0 tem quatro tipos temporais e JSON, YAML e XML não tem nenhum: deslocamento de data e hora (1979-05-27T07:32:00Z), data e hora local (1979-05-27T07:32:00, sem zona, deliberadamente), data local (1979-05-27) e hora local (07:32:00).

Cada uma se torna a string RFC 3339 exatamente como foi escrita, e a conversão informa para quais valores ela fez isso e qual dos quatro tipos cada uma era. A alternativa - emitir um único instante UTC para todos os quatro - moveria um horário local para uma zona que o documento se recusou explicitamente a declarar, o que é uma resposta errada e não com perdas.

A conversão de volta produz strings entre aspas, não datas. Uma viagem de ida e volta de TOML para JSON para TOML altera, portanto, os tipos desses valores. Não há como contornar isso sem inventar uma convenção que a ferramenta receptora teria que comcomcompartilhar, e inventar uma silenciosamente seria pior.

TOML inteiros são assinados 64 bits; Os números JSON são IEEE-754 duplos. Um número inteiro passado por 2^53 - 1 se torna uma string, com o caminho nomeado em um aviso, em vez de perder seus últimos dígitos devido a um arredondamento que você não notaria.

TOML não tem nulo. Uma chave nula é omitida da saída e nomeada em um aviso; um nulo dentro de um array se torna uma string vazia, porque removê-lo mudaria todos os índices posteriores. A raiz de um documento TOML é sempre uma tabela, portanto, um array ou um valor simples na raiz é recusado com uma frase dizendo o porquê.

YAML: âncoras, riachos e o problema da Noruega

YAML é lido com um esquema restrito que só pode produzir strings, números, booleanos, nulos, listas e mapas. Tags que constroem objetos arbitrários — !!js/function, !!python/object/apply, !!binary — são recusadas, e é por isso que a restrição existe: um carregador que as respeita é um construtor de objeto arbitrário vestindo roupas de arquivo de configuração.

Âncoras e aliases são resolvidos em dados repetidos. Um documento que ultrapassa um milhão de valores depois que seus aliases são seguidos é recusado em vez de congelar a guia; um alias recursivo é recusado completamente, porque nenhum outro formato aqui pode expressar um ciclo.

Um fluxo de vários documentos separados por --- torna-se uma matriz de documentos, e a conversão diz isso. Nenhum outro formato nesta ferramenta possui stream, portanto, um array é o único mapeamento honesto.

YAML proíbe uma chave de mapeamento repetida e cada analisador trata uma de maneira diferente. Esta ferramenta mantém o último valor — a regra JSON.parse usa — e informa o que aconteceu, com a posição da repetição. Descartar silenciosamente um documento seria pior; escolher silenciosamente um valor sem dizer isso seria pior ainda.

O problema da Noruega: em YAML 1.1, os escalares sem aspas y, sim, ligado, não, desligado e o código de país NÃO são todos resolvidos para booleanos, que é como uma lista de códigos de país se transforma em uma lista de verdadeiros e falsos. Esta ferramenta lê YAML 1.2, onde apenas verdadeiro e falso são booleanos, então NO permanece a string NO. Quando escreve YAML ele cita cada string que um analisador 1.1 interpretaria incorretamente - 'NO', 'yes', 'on', '1.0', '0755', '2001-12-14' - então a saída é segura para alimentar uma ferramenta que não foi movida para 1.2. Isso custa alguns caracteres de citação e garante correção.

Strings que se parecem com números mantêm suas aspas pelo mesmo motivo: "0755" permanece uma string em vez de se tornar 755, e "1.0" permanece uma string em vez de se tornar 1.

Os comentários se perdem em todas as direções. JSON, CSV e os outros não têm onde colocá-los e não há como adivinhar para onde devem voltar.

JSON a CSV: achatamento e o apóstrofo que interrompe uma fórmula

Uma matriz se torna as linhas, um registro por elemento. Um objeto cuja única propriedade contém um array usa esse array como linhas, porque {"users": [ ... ]} é esmagadoramente uma tabela com um rótulo - e a conversão diz em voz alta que foi isso que aconteceu. Qualquer outro objeto é uma única linha. Uma string vazia, número ou nulo é recusada: um retângulo precisa de registros.

Objetos e matrizes aninhados são achatados em nomes de colunas pontilhadas, com um ponto para chaves de objeto e índices de matriz: address.city, tags.0, tags.1. Um separador, uma regra. Uma chave que já contém um ponto torna o nome da coluna ambíguo com um caminho aninhado; a ferramenta alerta, em vez de inventar um esquema de fuga que nenhuma planilha entenderia.

As chaves são unidas em cada linha, na ordem vista pela primeira vez. Uma linha sem um campo obtém uma célula vazia em vez de uma coluna deslocada, e a conversão avisa que as linhas estavam irregulares. Um objeto vazio ou matriz vazia torna-se uma célula vazia em seu próprio caminho, em vez de desaparecer.

A cotação segue RFC 4180: um campo contendo o delimitador, uma aspa dupla, CR ou LF é colocado entre aspas duplas e uma aspa incorporada é escrita duas vezes. Os registros são separados por CRLF. Os campos com espaços em branco à esquerda ou à direita também são citados, porque, caso contrário, as planilhas os cortam silenciosamente. Unicode passa inalterado e uma marca de ordem de byte pode ser prefixada para planilhas que precisam de uma para ler UTF-8.

A injeção de fórmula é aquela que morde. Uma célula que começa com =, +, -, @, uma tabulação ou um retorno de carro é executada como uma fórmula pelo Excel, LibreOffice Calc e Planilhas Google no momento em que o arquivo é aberto. =cmd|'/c calc'!A1 é a demonstração que todos citam; =IMPORTXML(...) é aquele que manda a planilha silenciosamente para algum lugar. Um conversor que escreve tal string literalmente transformou seus dados na execução de código de outra pessoa, em um arquivo que parece inerte.

Portanto, uma célula de texto que começa com um desses caracteres é prefixada com um apóstrofo, que toda planilha principal lê como "isto é texto" e não aparece na célula. Os números são deixados de lado: um -5 numérico é um número, não uma fórmula. A contagem de células escapadas é relatada e o escape pode ser desligado — nesse caso a ferramenta diz claramente o que você acabou de desligar.

CSV não consegue diferenciar uma string vazia de uma nula. Ambos se tornam uma célula vazia e a conversão conta os nulos para que você saiba o que aconteceu.

Limites e o que acontece quando você atinge um

Cada formato tem um limite de caracteres, aplicado antes mesmo de um analisador ser baixado: 8 milhões para JSON, 4 milhões para XML e para uma fonte CSV, 2 milhões para YAML e TOML. Além disso, a ferramenta recusa o número exato, ao invés de se tornar uma guia que não responde e perde o que você colou.

A saída de CSV é adicionalmente limitada a 100,000 linhas e colunas 2,000, porque uma matriz profundamente aninhada se nivela em uma coluna por elemento e alguns megabytes de JSON podem se tornar uma tabela que nenhuma planilha abrirá.

A entrada vazia e somente com espaços em branco é relatada como vazia em vez de convertida em documento nulo ou vazio. A sintaxe inválida é relatada com uma linha e uma coluna em todos os quatro formatos legíveis.

Os próprios analisadores são baixados somente quando uma conversão precisa deles. Abrir o kit de ferramentas para decodificar um JWT não busca nenhum deles.

O que acontece com o que você cola

  • Cada conversão, hash, decodificação e comparação é executada na guia do seu navegador. Nenhuma entrada é carregada, registrada ou armazenada em um servidor, porque não há nenhum servidor envolvido depois que a página é carregada.
  • Hashes vêm da implementação de criptografia da Web do próprio navegador e UUIDs de seu gerador aleatório criptograficamente seguro. Nenhum dos dois envolve uma chamada de rede.
  • Nada do que você digita é gravado no armazenamento local ou em um cookie. Recarregar a página a descarta; fechar a guia a descarta.
  • A análise de todo o site é executada apenas no host de produção canônico configurado e é divulgada na Política de Privacidade; hosts locais e de visualização recusam. Valores colados, tokens, URLs e conteúdos de arquivos são excluídos dos próprios eventos analíticos de ToolAcre. A publicidade está desativada na configuração atual.
  • Dito isto: uma chave JWT ou API é uma credencial ativa. O hábito seguro é nunca colar um em uma página da web que você não escreveu, por mais confiáveis ​​que sejam suas afirmações – incluindo esta.

Questões

Por que meu documento XML falha com "declara um DOCTYPE"?

Porque contém uma declaração de tipo de documento, e este conversor recusa cada uma delas em vez de confiar em uma configuração do analisador para manipular entidades com segurança. Exclua DOCTYPE se o conteúdo for seu. Não há opção para permitir isso.

Por que meu datetime TOML voltou como uma string entre aspas?

Porque JSON, YAML e XML não têm tipo de data. A data e hora foi convertida no texto RFC 3339 como foi escrito, que é uma string em qualquer outro formato. A conversão de volta produz, portanto, uma string, e a ferramenta avisa no momento em que isso acontece, em vez de permitir que você descubra mais tarde.

Por que uma das minhas células CSV começa com um apóstrofo?

Porque seu texto começa com =, +, -, @, uma tabulação ou retorno de carro, e uma planilha executa essa célula como uma fórmula quando o arquivo é aberto. O apóstrofo marca a célula como texto; não faz parte do valor depois que a célula é lida. Você pode desligar o escape e a ferramenta lhe dirá o que isso significa.

Por que um único elemento XML repetido não é um array?

Porque XML não oferece nenhuma maneira de distinguir uma lista de um de um único valor. Ambos são escritos de forma idêntica. Adivinhar em qualquer direção seria errado na metade das vezes, então a ferramenta informa o que realmente está lá.

Posso converter CSV novamente em JSON aqui?

Ler CSV corretamente requer decidir sobre um delimitador, um dialeto de aspas, se a primeira linha é um cabeçalho e um tipo para cada célula. Um conversor que adivinha todos os quatro está errado silenciosamente, o que é a pior maneira de estar errado. Use uma ferramenta CSV que pergunte.

Por que "NÃO" não é convertido em falso?

Porque esse comportamento pertence a YAML 1.1 e esta ferramenta lê YAML 1.2, onde apenas verdadeiro e falso são booleanos. O comportamento 1.1 é a razão pela qual o código do país da Noruega é uma piada corrente no gerenciamento de configuração. Quando a ferramenta escreve YAML ela cita essas strings para que nenhum analisador 1.1 downstream possa interpretá-las incorretamente.

Limitações

  • CSV está escrito, nunca lido. Não há conversão de CSV para JSON aqui, por opção.
  • Os comentários se perdem em todas as direções, em todos os formatos que os possuem.
  • Uma data e hora TOML se torna uma string em todos os outros formatos, portanto, uma viagem de ida e volta TOML altera esses tipos. Não existe caminho sem perdas.
  • Um documento XML contendo um DOCTYPE é recusado liminarmente, inclusive os inofensivos, e a recusa não pode ser desativada.
  • Um único elemento XML repetido não pode ser distinguido de um não repetido, portanto, XML a JSON a XML nem sempre retorna a forma original.
  • XML conteúdo misto — texto intercalado com elementos filhos — perde a posição do texto em relação aos filhos e não pode fazer ida e volta.
  • Os valores de XML são strings, a menos que a inferência de tipo esteja ativada, porque XML não declara nenhum tipo; com inferência ativada, "0755" e "NO" estão sujeitos aos erros de leitura usuais.
  • TOML não tem nulo: chaves nulas são eliminadas da saída TOML e nulos dentro de arrays tornam-se strings vazias.
  • A raiz de um documento TOML deve ser uma tabela, portanto, um array ou escalar JSON não pode ser convertido em TOML.
  • Os números JSON são IEEE-754 duplos. Os números inteiros após 2^53 são convertidos em strings em vez de arredondados silenciosamente, o que altera seu tipo.
  • CSV não consegue distinguir uma string vazia de uma nula; ambos são escritos como uma célula vazia.
  • O nivelamento CSV usa um ponto para chaves de objeto e índices de array, portanto, uma chave que já contém um ponto produz um nome de coluna ambíguo que é avisado, mas não escapa.
  • YAML âncoras e aliases são resolvidos em vez de preservados; a saída não possui âncoras e um alias recursivo é recusado porque nenhum formato de destino pode expressar um ciclo.
  • A entrada é limitada por formato – 8 milhões de caracteres para JSON, 4 milhões para XML, 2 milhões de caracteres para YAML e TOML – e documentos grandes são recusados ​​em vez de processados ​​lentamente.
  • Nada aqui é validado em relação a um esquema. Um documento pode ser convertido de forma limpa e ainda assim estar errado para sua finalidade.