Skip to content

Commit 3563ab8

Browse files
committed
Fixing path when processing embedded resources
1 parent df68dff commit 3563ab8

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

convert/kfx/generate.go

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package kfx
22

33
import (
44
"context"
5+
"crypto/rand"
6+
"crypto/sha256"
57
"fmt"
8+
"math/big"
69
"os"
710
"sort"
811
"strings"
@@ -17,6 +20,7 @@ import (
1720
"fbc/convert/kfx/ionutil"
1821
"fbc/convert/kfx/model"
1922
"fbc/convert/kfx/symbols"
23+
"fbc/misc"
2024
)
2125

2226
// Generate creates the KFX output file.
@@ -31,7 +35,7 @@ func Generate(ctx context.Context, c *content.Content, outputPath string, cfg *c
3135

3236
log.Info("Generating KFX", zap.String("output", outputPath))
3337

34-
containerID := "CR!" + c.Book.Description.DocumentInfo.ID
38+
containerID := "CR!" + hashTo28Alphanumeric(c.Book.Description.DocumentInfo.ID)
3539

3640
// Minimal content fragment.
3741
type contentFragment struct {
@@ -611,7 +615,7 @@ func Generate(ctx context.Context, c *content.Content, outputPath string, cfg *c
611615

612616
data, err := container.Pack(&container.PackParams{
613617
ContainerID: containerID,
614-
KfxgenApplicationVersion: "kfxlib-20251012",
618+
KfxgenApplicationVersion: misc.GetAppName() + "-" + misc.GetVersion(),
615619
KfxgenPackageVersion: "",
616620
DocumentSymbols: prolog.DocSymbols,
617621
FormatCapabilities: builders.BuildFormatCapabilities(),
@@ -628,3 +632,47 @@ func Generate(ctx context.Context, c *content.Content, outputPath string, cfg *c
628632

629633
return nil
630634
}
635+
636+
const charsetCR = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
637+
638+
// randomAlphanumeric28 generates a random string of exactly 28 bytes
639+
// containing only uppercase Latin letters (A-Z) and digits (0-9).
640+
func randomAlphanumeric28() string {
641+
const length = 28
642+
643+
result := make([]byte, length)
644+
charsetLen := big.NewInt(int64(len(charsetCR)))
645+
646+
for i := range length {
647+
num, err := rand.Int(rand.Reader, charsetLen)
648+
if err != nil {
649+
panic(err)
650+
}
651+
result[i] = charsetCR[num.Int64()]
652+
}
653+
return string(result)
654+
}
655+
656+
// hashTo28Alphanumeric hashes the input string to produce exactly 28 bytes
657+
// containing only uppercase Latin letters (A-Z) and digits (0-9). It does this
658+
// deterministically - same input string will always produce the same output
659+
// string. If the input is empty, a random string is generated instead.
660+
func hashTo28Alphanumeric(input string) string {
661+
if input == "" {
662+
return randomAlphanumeric28()
663+
}
664+
665+
// Use SHA-256 to hash the input
666+
hash := sha256.Sum256([]byte(input))
667+
668+
// Map hash bytes to full alphanumeric charset (A-Z, 0-9)
669+
result := make([]byte, 28)
670+
671+
for i := range 28 {
672+
// Use hash bytes to deterministically select from charset
673+
idx := hash[i] % byte(len(charsetCR))
674+
result[i] = charsetCR[idx]
675+
}
676+
677+
return string(result)
678+
}

fb2/stylesheet.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"net/http"
66
"os"
7+
"path"
78
"path/filepath"
89
"regexp"
910
"strings"
@@ -260,7 +261,7 @@ func (fb *FictionBook) resolveStylesheetResource(ref cssExternalRef, binaryIndex
260261
}
261262

262263
// Set full path with directory
263-
resource.Filename = filepath.Join(dir, resource.Filename)
264+
resource.Filename = path.Join(dir, resource.Filename)
264265

265266
log.Info("Loaded stylesheet resource from file",
266267
zap.String("url", ref.URL),

0 commit comments

Comments
 (0)