refactor(qpdf): make embed-metadata logging context-aware

This commit is contained in:
Julien Neuhart
2026-08-12 21:50:14 +02:00
parent 8b2c15d5de
commit 05bde96334
2 changed files with 18 additions and 17 deletions

View File

@@ -454,7 +454,7 @@ func (engine *QPdf) EmbedFilesMetadata(ctx context.Context, logger *slog.Logger,
return err return err
} }
catalogRef, catalogValue, filespecRefs, updateObjects := patchFilespecMetadata(logger, objects, metadata) catalogRef, catalogValue, filespecRefs, updateObjects := patchFilespecMetadata(ctx, logger, objects, metadata)
if len(filespecRefs) == 0 { if len(filespecRefs) == 0 {
span.SetStatus(codes.Ok, "") span.SetStatus(codes.Ok, "")
return nil return nil
@@ -506,7 +506,7 @@ func parsePdfObjects(output []byte) (map[string]json.RawMessage, error) {
// metadata keys. It sets /AFRelationship and /Subtype on matching objects // metadata keys. It sets /AFRelationship and /Subtype on matching objects
// and returns the catalog reference, catalog value, filespec references, // and returns the catalog reference, catalog value, filespec references,
// and the update objects map. // and the update objects map.
func patchFilespecMetadata(logger *slog.Logger, objects map[string]json.RawMessage, metadata map[string]map[string]string) (string, map[string]any, []string, map[string]any) { func patchFilespecMetadata(ctx context.Context, logger *slog.Logger, objects map[string]json.RawMessage, metadata map[string]map[string]string) (string, map[string]any, []string, map[string]any) {
updateObjects := make(map[string]any) updateObjects := make(map[string]any)
var catalogRef string var catalogRef string
var catalogValue map[string]any var catalogValue map[string]any
@@ -556,7 +556,7 @@ func patchFilespecMetadata(logger *slog.Logger, objects map[string]json.RawMessa
if ef, ok := value["/EF"].(map[string]any); ok { if ef, ok := value["/EF"].(map[string]any); ok {
efRef, _ := ef["/F"].(string) efRef, _ := ef["/F"].(string)
if efRef != "" { if efRef != "" {
setStreamSubtype(logger, objects, updateObjects, efRef, mimeType) setStreamSubtype(ctx, logger, objects, updateObjects, efRef, mimeType)
} }
} }
} }
@@ -653,38 +653,38 @@ func (engine *QPdf) writeAndApplyUpdate(ctx context.Context, logger *slog.Logger
// setStreamSubtype finds a stream object by reference and sets the /Subtype // setStreamSubtype finds a stream object by reference and sets the /Subtype
// key in its dict. // key in its dict.
func setStreamSubtype(logger *slog.Logger, objects map[string]json.RawMessage, updateObjects map[string]any, ref, mimeType string) { func setStreamSubtype(ctx context.Context, logger *slog.Logger, objects map[string]json.RawMessage, updateObjects map[string]any, ref, mimeType string) {
objKey := ref objKey := ref
if !strings.HasPrefix(objKey, "obj:") { if !strings.HasPrefix(objKey, "obj:") {
objKey = "obj:" + objKey objKey = "obj:" + objKey
} }
raw, ok := objects[objKey] raw, ok := objects[objKey]
if !ok { if !ok {
logger.Warn(fmt.Sprintf("set stream subtype on %s: object not found", ref)) logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: object not found", ref))
return return
} }
var obj map[string]json.RawMessage var obj map[string]json.RawMessage
if err := json.Unmarshal(raw, &obj); err != nil { if err := json.Unmarshal(raw, &obj); err != nil {
logger.Warn(fmt.Sprintf("set stream subtype on %s: unmarshal object: %s", ref, err)) logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: unmarshal object: %s", ref, err))
return return
} }
streamRaw, ok := obj["stream"] streamRaw, ok := obj["stream"]
if !ok { if !ok {
logger.Warn(fmt.Sprintf("set stream subtype on %s: no stream key", ref)) logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: no stream key", ref))
return return
} }
var stream map[string]any var stream map[string]any
if err := json.Unmarshal(streamRaw, &stream); err != nil { if err := json.Unmarshal(streamRaw, &stream); err != nil {
logger.Warn(fmt.Sprintf("set stream subtype on %s: unmarshal stream: %s", ref, err)) logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: unmarshal stream: %s", ref, err))
return return
} }
dict, ok := stream["dict"].(map[string]any) dict, ok := stream["dict"].(map[string]any)
if !ok { if !ok {
logger.Warn(fmt.Sprintf("set stream subtype on %s: stream dict is not a map", ref)) logger.WarnContext(ctx, fmt.Sprintf("set stream subtype on %s: stream dict is not a map", ref))
return return
} }

View File

@@ -1,6 +1,7 @@
package qpdf package qpdf
import ( import (
"context"
"encoding/json" "encoding/json"
"log/slog" "log/slog"
"os" "os"
@@ -99,7 +100,7 @@ func TestPatchFilespecMetadata(t *testing.T) {
"factur-x.xml": {"relationship": "Data"}, "factur-x.xml": {"relationship": "Data"},
} }
catalogRef, _, filespecRefs, updateObjects := patchFilespecMetadata(logger, objects, metadata) catalogRef, _, filespecRefs, updateObjects := patchFilespecMetadata(context.Background(), logger, objects, metadata)
if catalogRef != "obj:1 0 R" { if catalogRef != "obj:1 0 R" {
t.Errorf("catalogRef = %q, want %q", catalogRef, "obj:1 0 R") t.Errorf("catalogRef = %q, want %q", catalogRef, "obj:1 0 R")
@@ -125,7 +126,7 @@ func TestPatchFilespecMetadata(t *testing.T) {
"factur-x.xml": {"relationship": "Data"}, "factur-x.xml": {"relationship": "Data"},
} }
_, _, filespecRefs, _ := patchFilespecMetadata(logger, objects, metadata) _, _, filespecRefs, _ := patchFilespecMetadata(context.Background(), logger, objects, metadata)
if len(filespecRefs) != 0 { if len(filespecRefs) != 0 {
t.Errorf("filespecRefs = %v, want empty", filespecRefs) t.Errorf("filespecRefs = %v, want empty", filespecRefs)
} }
@@ -139,7 +140,7 @@ func TestPatchFilespecMetadata(t *testing.T) {
"factur-x.xml": {"relationship": "Alternative"}, "factur-x.xml": {"relationship": "Alternative"},
} }
_, _, filespecRefs, updateObjects := patchFilespecMetadata(logger, objects, metadata) _, _, filespecRefs, updateObjects := patchFilespecMetadata(context.Background(), logger, objects, metadata)
if len(filespecRefs) != 1 { if len(filespecRefs) != 1 {
t.Fatalf("filespecRefs = %v, want 1 entry", filespecRefs) t.Fatalf("filespecRefs = %v, want 1 entry", filespecRefs)
} }
@@ -158,7 +159,7 @@ func TestPatchFilespecMetadata(t *testing.T) {
"factur-x.xml": {"mimeType": "text/xml"}, "factur-x.xml": {"mimeType": "text/xml"},
} }
_, _, _, updateObjects := patchFilespecMetadata(logger, objects, metadata) _, _, _, updateObjects := patchFilespecMetadata(context.Background(), logger, objects, metadata)
streamObj, ok := updateObjects["obj:3 0 R"] streamObj, ok := updateObjects["obj:3 0 R"]
if !ok { if !ok {
t.Fatal("expected obj:3 0 R in updateObjects") t.Fatal("expected obj:3 0 R in updateObjects")
@@ -223,7 +224,7 @@ func TestSetStreamSubtype(t *testing.T) {
} }
updateObjects := make(map[string]any) updateObjects := make(map[string]any)
setStreamSubtype(logger, objects, updateObjects, "obj:3 0 R", "text/xml") setStreamSubtype(context.Background(), logger, objects, updateObjects, "obj:3 0 R", "text/xml")
streamObj := updateObjects["obj:3 0 R"].(map[string]any)["stream"].(map[string]any) streamObj := updateObjects["obj:3 0 R"].(map[string]any)["stream"].(map[string]any)
dict := streamObj["dict"].(map[string]any) dict := streamObj["dict"].(map[string]any)
@@ -238,7 +239,7 @@ func TestSetStreamSubtype(t *testing.T) {
} }
updateObjects := make(map[string]any) updateObjects := make(map[string]any)
setStreamSubtype(logger, objects, updateObjects, "5 0 R", "application/pdf") setStreamSubtype(context.Background(), logger, objects, updateObjects, "5 0 R", "application/pdf")
if _, ok := updateObjects["obj:5 0 R"]; !ok { if _, ok := updateObjects["obj:5 0 R"]; !ok {
t.Error("expected obj:5 0 R in updateObjects") t.Error("expected obj:5 0 R in updateObjects")
@@ -249,7 +250,7 @@ func TestSetStreamSubtype(t *testing.T) {
objects := map[string]json.RawMessage{} objects := map[string]json.RawMessage{}
updateObjects := make(map[string]any) updateObjects := make(map[string]any)
setStreamSubtype(logger, objects, updateObjects, "obj:99 0 R", "text/xml") setStreamSubtype(context.Background(), logger, objects, updateObjects, "obj:99 0 R", "text/xml")
if len(updateObjects) != 0 { if len(updateObjects) != 0 {
t.Error("expected no updates for missing object") t.Error("expected no updates for missing object")
@@ -262,7 +263,7 @@ func TestSetStreamSubtype(t *testing.T) {
} }
updateObjects := make(map[string]any) updateObjects := make(map[string]any)
setStreamSubtype(logger, objects, updateObjects, "obj:3 0 R", "text/xml") setStreamSubtype(context.Background(), logger, objects, updateObjects, "obj:3 0 R", "text/xml")
if len(updateObjects) != 0 { if len(updateObjects) != 0 {
t.Error("expected no updates for non-stream object") t.Error("expected no updates for non-stream object")