Files
seaweedfs/weed/server/volume_server_parse_path_test.go
T
7y-9 8bff3b3213 fix(volume): reject overflowing needle ID deltas (#10342)
* fix: reject overflowing needle ID deltas

Problem: Parsing a file ID with a delta can wrap a valid maximum needle ID back to zero without returning an error.

Root cause: Needle.ParsePath added the parsed uint64 delta without checking whether the sum exceeded the needle ID range.

Fix: Compare the delta with the remaining uint64 capacity before addition and return a contextual overflow error when it does not fit.

Validation: go test ./weed/storage/needle -run ^TestNeedleParsePathRejectsDeltaOverflow$ -count=1; go test ./weed/storage/needle -count=1; git diff --check 10cdaf381875492a2c752d1038797e96ff18208f..HEAD
Co-authored-by: Codex <noreply@openai.com>

* fix: propagate needle ID delta parse errors

Co-authored-by: Codex <noreply@openai.com>

* print the needle id in hex in the delta overflow error

* batch delete: keep processing after a cookie mismatch

* rust volume: reject overflowing needle id deltas

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Chris Lu <chris.lu@gmail.com>
2026-07-15 23:24:04 -07:00

46 lines
1.4 KiB
Go

package weed_server
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
)
const overflowingNeedleDeltaFid = "1,ffffffffffffffff00000000_1"
func TestDeleteHandlerRejectsOverflowingNeedleDelta(t *testing.T) {
req := httptest.NewRequest(http.MethodDelete, "/"+overflowingNeedleDeltaFid, nil)
resp := httptest.NewRecorder()
(&VolumeServer{}).DeleteHandler(resp, req)
if resp.Code != http.StatusBadRequest {
t.Fatalf("DeleteHandler returned status %d, want %d", resp.Code, http.StatusBadRequest)
}
}
func TestBatchDeleteRejectsOverflowingNeedleDelta(t *testing.T) {
resp, err := (&VolumeServer{}).BatchDelete(context.Background(), &volume_server_pb.BatchDeleteRequest{
FileIds: []string{overflowingNeedleDeltaFid},
})
if err != nil {
t.Fatalf("BatchDelete returned error: %v", err)
}
if len(resp.Results) != 1 || resp.Results[0].Status != http.StatusBadRequest {
t.Fatalf("BatchDelete returned results %+v, want one bad request", resp.Results)
}
}
func TestQueryRejectsOverflowingNeedleDelta(t *testing.T) {
err := (&VolumeServer{}).Query(&volume_server_pb.QueryRequest{
FromFileIds: []string{overflowingNeedleDeltaFid},
}, nil)
if err == nil || !strings.Contains(err.Error(), "overflows needle id") {
t.Fatalf("Query returned error %v, want needle id overflow", err)
}
}