mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
* Propagate context through Extractor.Extract Adds ctx context.Context to the Extractor interface and all implementations so callers can cancel in-flight extractions. pdfExtractor passes the context down to GetPlainText(ctx), which checks ctx.Done() at each page boundary. When extractWithTimeout fires (deadline exceeded or parent cancel), it cancels the derived context via defer cancel(), and the PDF goroutine stops at the next page rather than running to completion, eliminating the heap growth that caused OOM on complex documents. For non-context-aware extractors (docconv, plain, archive) the context is accepted but not yet acted on; they continue to run to completion on a detached goroutine after the timeout, as before. The call site in channels/app/file.go passes rctx.Context() so request cancellation (e.g. HTTP disconnect) also propagates. * Use new mattermost/pdf fork * Update notice reflecting the new fork * Fail archiveExtractor.Extract early on ctx errors * Bump mattermost/pdf to cd8a834041c4 --------- Co-authored-by: Mattermost Build <[email protected]>
54 lines
2.1 KiB
Go
54 lines
2.1 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package docextractor
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestArchiveExtractorSkips7zip(t *testing.T) {
|
|
ae := &archiveExtractor{}
|
|
|
|
t.Run("7zip file with .7z extension returns empty string", func(t *testing.T) {
|
|
// Valid 7zip header (minimal)
|
|
sevenZipData := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00}
|
|
result, err := ae.Extract(context.Background(), "test.7z", bytes.NewReader(sevenZipData), 0)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, result)
|
|
})
|
|
|
|
t.Run("7zip content with wrong extension is still blocked", func(t *testing.T) {
|
|
// 7zip content disguised with .zip extension - should still be blocked via stream detection
|
|
sevenZipData := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00}
|
|
result, err := ae.Extract(context.Background(), "malicious.zip", bytes.NewReader(sevenZipData), 0)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, result)
|
|
})
|
|
|
|
t.Run("7zip at offset with .7z extension is blocked via filename", func(t *testing.T) {
|
|
junkPrefix := []byte{0x00, 0x00, 0x00, 0x00}
|
|
sevenZipSig := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00}
|
|
dataWithOffset := append(junkPrefix, sevenZipSig...)
|
|
result, err := ae.Extract(context.Background(), "test.7z", bytes.NewReader(dataWithOffset), 0)
|
|
require.NoError(t, err)
|
|
assert.Empty(t, result)
|
|
})
|
|
|
|
t.Run("7zip at offset with wrong extension fails safely", func(t *testing.T) {
|
|
// Edge case: 7zip content at offset with non-.7z extension.
|
|
// Our check won't catch it (ByName=false, ByStream=false), but archives.FileSystem
|
|
// also won't identify it as 7zip, so it fails to extract rather than triggering OOM.
|
|
junkPrefix := []byte{0x00, 0x00, 0x00, 0x00}
|
|
sevenZipSig := []byte{0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c, 0x00, 0x00}
|
|
dataWithOffset := append(junkPrefix, sevenZipSig...)
|
|
_, err := ae.Extract(context.Background(), "malicious.zip", bytes.NewReader(dataWithOffset), 0)
|
|
assert.Error(t, err) // fails to extract as any valid archive format
|
|
})
|
|
}
|