Add actual inline data to JSON output in xl-meta (#19958)

Add the inlined data as base64 encoded field and try to add a string version if feasible.

Example:

```
λ xl-meta -data xl.meta
{
  "8e03504e-1123-4957-b272-7bc53eda0d55": {
    "bitrot_valid": true,
    "bytes": 58,
    "data_base64": "Z29sYW5nLm9yZy94L3N5cyB2MC4xNS4wIC8=",
    "data_string": "golang.org/x/sys v0.15.0 /"
}
```

The string will have quotes, newlines escaped to produce valid JSON.

If content isn't valid utf8 or the encoding otherwise fails, only the base64 data will be added.

`-export` can still be used separately to extract the data as files (including bitrot).
This commit is contained in:
Klaus Post 2024-06-20 07:46:44 -07:00 committed by GitHub
parent 95e4cbbfde
commit 3e6dc02f8f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -20,6 +20,7 @@ package main
import (
"bytes"
"crypto/md5"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/json"
@ -34,6 +35,7 @@ import (
"strconv"
"strings"
"time"
"unicode/utf8"
"github.com/google/uuid"
"github.com/klauspost/compress/zip"
@ -237,7 +239,7 @@ FLAGS:
}
if c.Bool("data") {
b, err := data.json()
b, err := data.json(true)
if err != nil {
return nil, err
}
@ -562,7 +564,7 @@ func (x xlMetaInlineData) versionOK() bool {
return x[0] > 0 && x[0] <= xlMetaInlineDataVer
}
func (x xlMetaInlineData) json() ([]byte, error) {
func (x xlMetaInlineData) json(value bool) ([]byte, error) {
if len(x) == 0 {
return []byte("{}"), nil
}
@ -607,6 +609,17 @@ func (x xlMetaInlineData) json() ([]byte, error) {
} else {
s += ", \"bitrot_valid\": false"
}
if value {
if utf8.Valid(data) {
// Encode as JSON string.
b, err := json.Marshal(string(data))
if err == nil {
s += `, "data_string": ` + string(b)
}
}
// Base64 encode.
s += `, "data_base64": "` + base64.StdEncoding.EncodeToString(data) + `"`
}
s += "}"
}
res = append(res, []byte(s)...)