O que é esse conjunto de dados aparentemente base64 definido por setfattr?

4

Eu escrevi um pequeno script de shell que simplesmente agrupa setfattr em um formato um pouco mais conveniente para configurar o atributo estendido que corresponde a um comentário de texto livre:

#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -d -m '^user.xdg.comment$' "$1"

Para armazenar comentários ASCII dos EUA como xattrs, isso funciona muito bem. No entanto, se eu tentar definir um comentário que contenha caracteres ASCII não-US, ele retornará o que parece ser dados codificados em Base64:

$ touch xyz
$ set-comment xyz åäöåä
# file: xyz
user.xdg.comment=0sw6XDpMO2w6XDpA==
$ 

Mas não é apenas o Base64:

$ printf "0sw6XDpMO2w6XDpA==" | \base64 --decode
��:\:L;l:\:@base64: invalid input
$ 

Na maioria das vezes, eu recebo apenas lixo aleatório. Algumas vezes, assim, o decodificador Base64 lança "entrada inválida" de volta para mim.

O que é essa string? Qual é a relação com o valor de entrada original? Como faço para ir de qual getfattr me devolve ao valor de entrada original (como åäöåä neste caso)?

setfattr --version no meu sistema responde com setfattr 2.4.46 . Eu estou executando a versão empacotada pelo Debian Wheezy. No caso improvável de que seja importante, estou executando o ZFS On Linux 0.6.3 (também vi o mesmo comportamento com o 0.6.2) no kernel Wheezy padrão.

    
por a CVn 23.06.2014 / 17:48

1 resposta

4

Eu fiquei um pouco curioso ao ler essa questoion, então vamos fazer alguns "forense" :

Primeiro tentando o oposto:

Como o åäöåä é codificado em Base64?

$ echo åäöåä | base64
w6XDpMO2w6XDpAo=

Isso claramente se parece muito com o 0sw6XDpMO2w6XDpA== que você tem. Há um 0s extra no início e o final não corresponde exatamente. Suprimindo a nova linha no final de åäöåä (inserida automaticamente por echo ), obtemos:

$ echo -n åäöåä | base64
w6XDpMO2w6XDpA==

Este é exatamente o user.xdg.comment -value, exceto o 0s no início.

Conclusão

O comentário é Base64 codificado e prefixado com 0s , e testar algumas outras strings confirma isso.

Exemplo:

$ ./set-comment xyz 日本語
# file: xyz
user.xdg.comment=0s5pel5pys6Kqe

$ base64 -d <<<'5pel5pys6Kqe' ; echo
日本語

(onde ; echo é para não atrapalhar o próximo prompt, pois a saída de base64 não termina em uma nova linha.)

No entanto ...

Isso mostra apenas que nesses casos (onde o comentário é não-ASCII), ele é codificado em Base64 e prefixado com 0s .

A resposta "real"

Depois de fazer isso, tive a esplêndida idéia de verificar a página de manual para getfattr e menciona, entre outras coisas:

Em relação à opção -e en, --encoding=en

Encode values after retrieving them. Valid values of en are "text", "hex", and "base64". Values encoded as text strings are enclosed in double quotes ("), while strings encoded as hexidecimal and base64 are prefixed with 0x and 0s, respectively.

Então, altere seu script para:

(Arquivo set-comment :)

#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -e text -d -m '^user.xdg.comment$' "$1"

sempre imprime o atributo como texto, dando, por exemplo:

$ ./set-comment xyz åäöåä   # with fixed script
# file: xyz
user.xdg.comment="åäöåä"

No entanto, ainda existem algumas ressalvas ... como:

$ ./set-comment xyz 0x414243
# file: xyz
user.xdg.comment="ABC"

e

$ ./set-comment xyz 0s5pel5pys6Kqe
# file: xyz
user.xdg.comment="日本語"

em que a saída não corresponde à entrada.

Estes podem ser corrigidos “massageando” o argumento em um formato que setfattr gosta. Veja man setfattr .

    
por 23.06.2014 / 19:57

Tags