From f1af90e301c48882f9b88155c991fbe4c30b3b9c Mon Sep 17 00:00:00 2001 From: urvisavla Date: Fri, 13 Mar 2026 16:24:36 -0700 Subject: [PATCH 1/2] Update changelog for v0.3.0 release (#5920) --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ffa3e94ff..88f4e39fb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,14 @@ This monorepo contains a number of sdk's: Official project releases may be found here: https://github.com/stellar/go-stellar-sdk/releases ## Pending +## [0.3.0] + +### Security Fixes +* historyarchive: Added size bound to `GetPathHAS` to prevent resource exhaustion ([#5918](https://github.com/stellar/go-stellar-sdk/pull/5918)) + +### New Features +* xdr: Added `SafeUnmarshalBase64WithOptions` and regenerated with output size tracking ([#5916](https://github.com/stellar/go-stellar-sdk/pull/5916)) + ## [0.2.0] ### Breaking Changes From cbd446204cd3eccb41857896936b5bf96fc2294d Mon Sep 17 00:00:00 2001 From: urvisavla Date: Mon, 23 Mar 2026 15:48:49 -0700 Subject: [PATCH 2/2] support/datastore: Fix ListFilePath for datastore bucket with no prefix (#5923) * Fix ListFilePath for datastore destination_bucket_path with no prefix (only the bucket name) * Simplify fullPrefix logic --- support/datastore/gcs.go | 15 +++++---------- support/datastore/gcs_test.go | 34 ++++++++++++++++++++++++++++++++++ support/datastore/s3.go | 15 +++++---------- support/datastore/s3_test.go | 22 ++++++++++++++++++++++ 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/support/datastore/gcs.go b/support/datastore/gcs.go index 1c3393acdc..0e69376151 100644 --- a/support/datastore/gcs.go +++ b/support/datastore/gcs.go @@ -209,16 +209,11 @@ func (b GCSDataStore) putFile(ctx context.Context, filePath string, in io.Writer func (b GCSDataStore) ListFilePaths(ctx context.Context, options ListFileOptions) ([]string, error) { var fullPrefix string - // When 'prefix' is empty, ensure the base prefix ends with a slash (e.g., "a/b/") - // so the query returns only objects within that directory, not similarly named paths like "a/b-1". - if options.Prefix == "" { - fullPrefix = b.prefix - if !strings.HasSuffix(fullPrefix, "/") { - fullPrefix += "/" - } - } else { - // Join the caller-provided prefix with the datastore prefix - fullPrefix = path.Join(b.prefix, options.Prefix) + // Ensure the prefix ends with a slash so the query returns only objects + // within that directory, not similarly named paths like "a/b-1". + fullPrefix = path.Join(b.prefix, options.Prefix) + if fullPrefix != "" { + fullPrefix += "/" } var StartAfter string diff --git a/support/datastore/gcs_test.go b/support/datastore/gcs_test.go index 516d61583d..2f56eeffb3 100644 --- a/support/datastore/gcs_test.go +++ b/support/datastore/gcs_test.go @@ -437,6 +437,40 @@ func TestGCSListFilePaths(t *testing.T) { require.Equal(t, []string{"a", "b"}, paths) } +func TestGCSListFilePaths_NoPrefix(t *testing.T) { + server := fakestorage.NewServer([]fakestorage.Object{ + { + ObjectAttrs: fakestorage.ObjectAttrs{BucketName: "test-bucket", Name: "a"}, + Content: []byte("1"), + }, + { + ObjectAttrs: fakestorage.ObjectAttrs{BucketName: "test-bucket", Name: "b"}, + Content: []byte("1"), + }, + { + ObjectAttrs: fakestorage.ObjectAttrs{BucketName: "test-bucket", Name: "c"}, + Content: []byte("1"), + }, + }) + defer server.Stop() + + store, err := FromGCSClient(context.Background(), server.Client(), "test-bucket") + require.NoError(t, err) + t.Cleanup(func() { _ = store.Close() }) + + paths, err := store.ListFilePaths(context.Background(), ListFileOptions{}) + require.NoError(t, err) + require.Equal(t, []string{"a", "b", "c"}, paths) + + paths, err = store.ListFilePaths(context.Background(), ListFileOptions{Limit: 2}) + require.NoError(t, err) + require.Equal(t, []string{"a", "b"}, paths) + + paths, err = store.ListFilePaths(context.Background(), ListFileOptions{StartAfter: "a"}) + require.NoError(t, err) + require.Equal(t, []string{"b", "c"}, paths) +} + func TestGCSListFilePaths_WithPrefix(t *testing.T) { server := fakestorage.NewServer([]fakestorage.Object{ { diff --git a/support/datastore/s3.go b/support/datastore/s3.go index 62b2901b70..81817963ce 100644 --- a/support/datastore/s3.go +++ b/support/datastore/s3.go @@ -288,16 +288,11 @@ func (b S3DataStore) putFile(ctx context.Context, filePath string, in io.WriterT func (b S3DataStore) ListFilePaths(ctx context.Context, options ListFileOptions) ([]string, error) { var fullPrefix string - // When 'prefix' is empty, ensure the base prefix ends with a slash (e.g., "a/b/") - // so the query returns only objects within that directory, not similarly named paths like "a/b-1". - if options.Prefix == "" { - fullPrefix = b.prefix - if !strings.HasSuffix(fullPrefix, "/") { - fullPrefix += "/" - } - } else { - // Join the caller-provided prefix with the datastore prefix - fullPrefix = path.Join(b.prefix, options.Prefix) + // Ensure the prefix ends with a slash so the query returns only objects + // within that directory, not similarly named paths like "a/b-1". + fullPrefix = path.Join(b.prefix, options.Prefix) + if fullPrefix != "" { + fullPrefix += "/" } var StartAfter string diff --git a/support/datastore/s3_test.go b/support/datastore/s3_test.go index c89546085a..33830e715f 100644 --- a/support/datastore/s3_test.go +++ b/support/datastore/s3_test.go @@ -256,6 +256,28 @@ func TestS3ListFilePaths(t *testing.T) { require.Equal(t, []string{"a", "b"}, paths) } +func TestS3ListFilePaths_NoPrefix(t *testing.T) { + ctx := context.Background() + store, teardown := setupTestS3DataStore(t, ctx, "test-bucket", map[string]mockS3Object{ + "a": {body: []byte("1")}, + "b": {body: []byte("1")}, + "c": {body: []byte("1")}, + }) + defer teardown() + + paths, err := store.ListFilePaths(context.Background(), ListFileOptions{}) + require.NoError(t, err) + require.Equal(t, []string{"a", "b", "c"}, paths) + + paths, err = store.ListFilePaths(context.Background(), ListFileOptions{Limit: 2}) + require.NoError(t, err) + require.Equal(t, []string{"a", "b"}, paths) + + paths, err = store.ListFilePaths(context.Background(), ListFileOptions{StartAfter: "a"}) + require.NoError(t, err) + require.Equal(t, []string{"b", "c"}, paths) +} + func TestS3ListFilePaths_WithPrefix(t *testing.T) { ctx := context.Background() store, teardown := setupTestS3DataStore(t, ctx, "test-bucket/objects/testnet", map[string]mockS3Object{