summaryrefslogtreecommitdiff
path: root/internal/extract
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 23:07:57 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 23:07:57 +0200
commitc66a842ce4679a3ffa5504dad39b1402bea75e9f (patch)
tree9e9db5e569b9f16a4ca4e66d0a5b0f456a186ece /internal/extract
parentb013e5fb87580e4cab0d85a0d2c8bb402c610413 (diff)
downloadkrino-3a1006ed2f2a178018efe157daf8fcb377d29c3c.tar.gz
krino-3a1006ed2f2a178018efe157daf8fcb377d29c3c.zip
plan 10 re-check: cut run column, damaged undo run, emptied directory cleanup, text turning binary, explain flags, interrupt docsv0.0.7
Diffstat (limited to 'internal/extract')
-rw-r--r--internal/extract/extract.go7
-rw-r--r--internal/extract/plain.go4
-rw-r--r--internal/extract/plain_test.go9
3 files changed, 14 insertions, 6 deletions
diff --git a/internal/extract/extract.go b/internal/extract/extract.go
index ad51c00..376e09b 100644
--- a/internal/extract/extract.go
+++ b/internal/extract/extract.go
@@ -17,12 +17,17 @@ import (
// Version is the version of the text this package extracts. Bump it
// whenever a change could make any format's text differ, so every keyword
// cache built from the old text is discarded (Fingerprint).
-const Version = 1
+const Version = 2
var (
// ErrUnsupported is returned when the format carries no text krino
// knows how to extract.
ErrUnsupported = errors.New("no text in this format")
+ // ErrMixed is returned for a file of no known extension whose first
+ // 8 KiB read as text but which holds a NUL or invalid UTF-8 further on.
+ // Unlike ErrUnsupported it is a read failure: the text it began with
+ // could hold a keyword (plan 10 re-check R4).
+ ErrMixed = errors.New("text at the start, binary data further on")
// ErrTooLarge is returned when the file is larger than the configured
// max-read; nothing is read in that case.
ErrTooLarge = errors.New("larger than max-read")
diff --git a/internal/extract/plain.go b/internal/extract/plain.go
index d245a41..f7470be 100644
--- a/internal/extract/plain.go
+++ b/internal/extract/plain.go
@@ -38,7 +38,7 @@ func readDecoded(path string) (string, error) {
// the sample alone (UTF-16 text is full of NUL bytes by design), but a
// sample that merely looks like UTF-8 must hold for the WHOLE file — no
// NUL byte anywhere, and no invalid UTF-8 anywhere past the sample — or
-// the file is ErrUnsupported after all; the Latin-1 fallback in decode
+// the file is ErrMixed, unreadable; the Latin-1 fallback in decode
// never applies to a sniffed file, only to a file whose extension already
// names it as text. D2: when the file continues past the sample (n ==
// sniffSize), the validity check is run against a trimmed copy with any
@@ -81,7 +81,7 @@ func sniffText(path string) (string, error) {
return decode(data), nil
}
if !utf8.Valid(data) || bytes.Contains(data, []byte{0}) {
- return "", ErrUnsupported
+ return "", ErrMixed
}
return decode(data), nil
}
diff --git a/internal/extract/plain_test.go b/internal/extract/plain_test.go
index 045ea26..f49caf8 100644
--- a/internal/extract/plain_test.go
+++ b/internal/extract/plain_test.go
@@ -154,12 +154,15 @@ func TestToolsListedInOrder(t *testing.T) {
// but the file goes on to hold an invalid UTF-8 byte and a NUL past that
// sample — sniffText must reject the whole file, not just decode what the
// sample alone promised (it must not fall back to Latin-1 the way a known
-// text extension would).
+// text extension would). It is not "no text in this format" either: the
+// text it began with could hold a keyword, so it is ErrMixed, a read
+// failure, and a content exclude fails closed on it (plan 10 re-check R4).
func TestSniffWholeFileMustBeValid(t *testing.T) {
e := newWithPath("")
data := append([]byte(strings.Repeat("x", 8192)), 0xFF, 0x00)
- if _, err := text(t, e, file(t, "blob.data", data), 0); !errors.Is(err, ErrUnsupported) {
- t.Errorf("got %v, want ErrUnsupported", err)
+ _, err := text(t, e, file(t, "blob.data", data), 0)
+ if !errors.Is(err, ErrMixed) || errors.Is(err, ErrUnsupported) {
+ t.Errorf("got %v, want ErrMixed and not ErrUnsupported", err)
}
}