diff --git a/backend/walk.go b/backend/walk.go index cd6991bd..d34c223e 100644 --- a/backend/walk.go +++ b/backend/walk.go @@ -108,8 +108,11 @@ func Walk(fileSystem fs.FS, prefix, delimiter, marker string, max int32, getObj if !pastMarker { if path == marker { pastMarker = true + return nil + } + if path < marker { + return nil } - return nil } // If object doesn't have prefix, don't include in results. diff --git a/integration/action-tests.go b/integration/action-tests.go index 659a765e..ec4402d3 100644 --- a/integration/action-tests.go +++ b/integration/action-tests.go @@ -75,6 +75,7 @@ func TestListObjects(s *S3Conf) { ListObjects_max_keys_0(s) ListObjects_delimiter(s) ListObjects_max_keys_none(s) + ListObjects_marker_not_from_obj_list(s) } func TestDeleteObject(s *S3Conf) { diff --git a/integration/tests.go b/integration/tests.go index 54779e40..be44dddd 100644 --- a/integration/tests.go +++ b/integration/tests.go @@ -1534,6 +1534,36 @@ func ListObjects_max_keys_none(s *S3Conf) { }) } +func ListObjects_marker_not_from_obj_list(s *S3Conf) { + testName := "ListObjects_marker_not_from_obj_list" + actionHandler(s, testName, func(s3client *s3.Client, bucket string) error { + err := putObjects(s3client, []string{"foo", "bar", "baz", "qux", "hello", "xyz"}, bucket) + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), shortTimeout) + out, err := s3client.ListObjects(ctx, &s3.ListObjectsInput{ + Bucket: &bucket, + Marker: getPtr("ceil"), + }) + cancel() + if err != nil { + return err + } + + for _, el := range out.Contents { + fmt.Println(*el.Key) + } + + if !compareObjects([]string{"foo", "qux", "hello", "xyz"}, out.Contents) { + return fmt.Errorf("expected output to be %v, instead got %v", []string{"foo", "qux", "hello", "xyz"}, out.Contents) + } + + return nil + }) +} + func DeleteObject_non_existing_object(s *S3Conf) { testName := "DeleteObject_non_existing_object" actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {