Compare commits

..
Author SHA1 Message Date
2995e0c4d9 Cap JXL decode area and allow RTF text preview (#3352)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Graham Steffaniak <gtsteffaniak@users.noreply.github.com>
2026-11-07 10:34:34 -06:00
Jay Hemnani 84b3b8ebd2 fix(users): save the prompt close button and new file templates when editing a user (#3342) 2026-11-06 17:26:44 -06:00
Graham Steffaniakandcoderabbitai[bot] 28f067f808 Leftover folio docs fix (#3347)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-11-06 13:47:39 -06:00
6 changed files with 45 additions and 6 deletions

No files matched your search

+10 -4
View File
@@ -80,6 +80,11 @@ var heifImageExts = map[string]bool{
const heicDecodeMaxEdge = 16384
// stillImageMaxSourcePixels caps the original image area (width×height) passed to
// go-media for HEIC, JPEG XL, and camera RAW decode. JPEG XL honors it today
// (~50 MiB of 8-bit RGB at 4096×4096); other still formats ignore the field.
const stillImageMaxSourcePixels = 4096 * 4096
// cameraRawExts match go-media rawpreview formats (also iteminfo raw extensions).
var cameraRawExts = map[string]bool{
".cr2": true, ".cr3": true, ".nef": true, ".nrw": true, ".arw": true, ".srf": true, ".sr2": true,
@@ -628,10 +633,11 @@ func stillImageJPEG(path string, maxW, maxH, quality int, op string, supported f
quality = 85
}
res, err := media.Thumbnail(f, size, media.ThumbnailOptions{
MaxWidth: maxW,
MaxHeight: maxH,
Format: "jpeg",
Quality: quality,
MaxWidth: maxW,
MaxHeight: maxH,
Format: "jpeg",
Quality: quality,
MaxSourcePixels: stillImageMaxSourcePixels,
})
if err != nil {
logFail(err)
+23
View File
@@ -2,11 +2,13 @@ package gomedia
import (
"bytes"
"errors"
"image/jpeg"
"os"
"path/filepath"
"testing"
"github.com/gtsteffaniak/go-media/pkg/media"
"github.com/stretchr/testify/require"
)
@@ -66,3 +68,24 @@ func TestJXLJPEGMissingFileReturnsFalse(t *testing.T) {
require.False(t, ok)
require.Empty(t, data)
}
// JPEG XL above stillImageMaxSourcePixels must fail with go-media's ErrUnsupported
// and return ok=false (no ffmpeg fallback).
func TestJXLJPEGRejectsOversizedSource(t *testing.T) {
withGate(t, false)
f, err := os.Open(fixtureJXL)
require.NoError(t, err)
defer f.Close()
info, err := f.Stat()
require.NoError(t, err)
_, err = media.Thumbnail(f, info.Size(), media.ThumbnailOptions{
MaxWidth: 256,
MaxHeight: 256,
Format: "jpeg",
Quality: 85,
MaxSourcePixels: 1,
})
require.Error(t, err)
require.True(t, errors.Is(err, media.ErrUnsupported), "oversized JXL must surface ErrUnsupported, got %v", err)
}
@@ -567,6 +567,7 @@ func TextPreviewKind(ext string) string {
// Do not add mimetypes shared with binaries (e.g. application/x-msdownload for .exe).
var textPreviewMimeTypes = map[string]bool{
"application/json": true,
"application/rtf": true,
"application/yaml": true,
"application/x-yaml": true,
"application/sql": true,
@@ -25,7 +25,7 @@ func TestIsTextPreviewable(t *testing.T) {
for _, mt := range []string{"text/plain", "text/markdown", "text/lyrics", "text/x-go", "text/html"} {
require.True(t, IsTextPreviewable(mt), mt)
}
for _, mt := range []string{"application/json", "application/yaml", "application/sql", "application/x-sh", "application/x-php", "application/x-powershell", "application/x-tex"} {
for _, mt := range []string{"application/json", "application/yaml", "application/sql", "application/x-sh", "application/x-php", "application/x-powershell", "application/x-tex", "application/rtf", "text/rtf"} {
require.True(t, IsTextPreviewable(mt), mt)
}
// Mimetypes shared with binaries (.exe, .bat via application/x-msdownload) must stay non-previewable.
@@ -295,6 +295,8 @@ const PROFILE_SNAPSHOT_FIELDS = [
"debugOffice",
"viewMode",
"gallerySize",
"promptRightCloseButton",
"newFileTemplate",
];
export default {
+8 -1
View File
@@ -5,6 +5,7 @@ const { globalsMock } = vi.hoisted(() => ({
globalsMock: {
textPreviewMimeTypes: [
"application/json",
"application/rtf",
"application/yaml",
"application/x-yaml",
"application/sql",
@@ -66,7 +67,13 @@ describe("isTextPreviewableType", () => {
});
it("is true for text-extension mimetypes that are not text/*", () => {
for (const mt of ["application/json", "application/yaml", "application/sql", "application/x-sh", "application/x-php", "application/x-powershell", "application/x-tex"]) {
for (const mt of ["application/json", "application/rtf", "application/yaml", "application/sql", "application/x-sh", "application/x-php", "application/x-powershell", "application/x-tex"]) {
expect(isTextPreviewableType(mt), mt).toBe(true);
}
});
it("is true for RTF mimetypes", () => {
for (const mt of ["application/rtf", "text/rtf", "application/rtf; charset=windows-1252"]) {
expect(isTextPreviewableType(mt), mt).toBe(true);
}
});