Skip to content

Commit

Permalink
Escape single-quote characters in partition and row keys (#21232)
Browse files Browse the repository at this point in the history
* Escapse single-quote characters in partition and row keys

* update dependencies

* fix swapped test parameters

add requirement of non-empty slice to prevent panic if it is
updated all test recordings

* add unit test for prepareKey

* prepare for release

add empty string test
  • Loading branch information
jhendrixMSFT authored Jul 20, 2023
1 parent 8227ec1 commit 6d3bfc2
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 70 deletions.
8 changes: 3 additions & 5 deletions sdk/data/aztables/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# Release History

## 1.0.2 (Unreleased)

### Features Added

### Breaking Changes
## 1.0.2 (2023-07-20)

### Bugs Fixed
* Escape single-quote characters in partition and row keys.

### Other Changes
* Update dependencies.

## 1.0.1 (2022-06-16)

Expand Down
2 changes: 1 addition & 1 deletion sdk/data/aztables/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "go",
"TagPrefix": "go/data/aztables",
"Tag": "go/data/aztables_abcca51964"
"Tag": "go/data/aztables_45893b48dc"
}
2 changes: 1 addition & 1 deletion sdk/data/aztables/autorest.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ output-folder: internal
tag: package-2019-02
credential-scope: none
use: "@autorest/[email protected]"
module-version: 1.0.1
module-version: 1.0.2
security: "AADToken"
security-scopes: "https://storage.azure.com/.default"
modelerfour:
Expand Down
20 changes: 10 additions & 10 deletions sdk/data/aztables/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ func (t *Client) GetEntity(ctx context.Context, partitionKey string, rowKey stri
}

genOptions, queryOptions := options.toGenerated()
resp, err := t.client.QueryEntityWithPartitionAndRowKey(ctx, generated.Enum1Three0, t.name, partitionKey, rowKey, genOptions, queryOptions)
resp, err := t.client.QueryEntityWithPartitionAndRowKey(ctx, generated.Enum1Three0, t.name, prepareKey(partitionKey), prepareKey(rowKey), genOptions, queryOptions)
if err != nil {
return GetEntityResponse{}, err
}
Expand Down Expand Up @@ -375,7 +375,7 @@ func (t *Client) DeleteEntity(ctx context.Context, partitionKey string, rowKey s
nilEtag := azcore.ETag("*")
options.IfMatch = &nilEtag
}
resp, err := t.client.DeleteEntity(ctx, generated.Enum1Three0, t.name, partitionKey, rowKey, string(*options.IfMatch), options.toGenerated(), &generated.QueryOptions{})
resp, err := t.client.DeleteEntity(ctx, generated.Enum1Three0, t.name, prepareKey(partitionKey), prepareKey(rowKey), string(*options.IfMatch), options.toGenerated(), &generated.QueryOptions{})
if err != nil {
return DeleteEntityResponse{}, err
}
Expand Down Expand Up @@ -477,8 +477,8 @@ func (t *Client) UpdateEntity(ctx context.Context, entity []byte, options *Updat
ctx,
generated.Enum1Three0,
t.name,
partKey,
rowkey,
prepareKey(partKey),
prepareKey(rowkey),
options.toGeneratedMergeEntity(mapEntity),
&generated.QueryOptions{},
)
Expand All @@ -491,8 +491,8 @@ func (t *Client) UpdateEntity(ctx context.Context, entity []byte, options *Updat
ctx,
generated.Enum1Three0,
t.name,
partKey,
rowkey,
prepareKey(partKey),
prepareKey(rowkey),
options.toGeneratedUpdateEntity(mapEntity),
&generated.QueryOptions{},
)
Expand Down Expand Up @@ -580,8 +580,8 @@ func (t *Client) UpsertEntity(ctx context.Context, entity []byte, options *Upser
ctx,
generated.Enum1Three0,
t.name,
partKey,
rowkey,
prepareKey(partKey),
prepareKey(rowkey),
&generated.TableClientMergeEntityOptions{TableEntityProperties: mapEntity},
&generated.QueryOptions{},
)
Expand All @@ -594,8 +594,8 @@ func (t *Client) UpsertEntity(ctx context.Context, entity []byte, options *Upser
ctx,
generated.Enum1Three0,
t.name,
partKey,
rowkey,
prepareKey(partKey),
prepareKey(rowkey),
&generated.TableClientUpdateEntityOptions{TableEntityProperties: mapEntity},
&generated.QueryOptions{},
)
Expand Down
3 changes: 2 additions & 1 deletion sdk/data/aztables/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func TestMergeEntity(t *testing.T) {
qResp, err = pager.NextPage(ctx)
require.NoError(t, err)
}
require.NotEmpty(t, qResp.Entities)
postMerge := qResp.Entities[0]
var unmarshalledPostMerge map[string]interface{}
err = json.Unmarshal(postMerge, &unmarshalledPostMerge)
Expand Down Expand Up @@ -216,7 +217,7 @@ func TestInsertEntity(t *testing.T) {
defer delete()

// 1. Create Basic Entity
entityToCreate := createSimpleEntity(1, "partition")
entityToCreate := createSimpleEntityWithRowKey(1, "parti'tion", "one'")
marshalled, err := json.Marshal(entityToCreate)
require.NoError(t, err)

Expand Down
7 changes: 6 additions & 1 deletion sdk/data/aztables/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type EDMEntity struct {
// MarshalJSON implements the json.Marshal method
func (e EDMEntity) MarshalJSON() ([]byte, error) {
entity := map[string]interface{}{}
entity["PartitionKey"], entity["RowKey"] = e.PartitionKey, e.RowKey
entity["PartitionKey"], entity["RowKey"] = prepareKey(e.PartitionKey), prepareKey(e.RowKey)

for propName, propValue := range e.Properties {
entity[propName] = propValue
Expand Down Expand Up @@ -202,3 +202,8 @@ func (e *EDMDateTime) UnmarshalText(data []byte) error {
*e = EDMDateTime(t)
return nil
}

func prepareKey(key string) string {
// escape any single-quotes
return strings.ReplaceAll(key, "'", "''")
}
11 changes: 11 additions & 0 deletions sdk/data/aztables/entity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,3 +209,14 @@ func TestEntityUnicode(t *testing.T) {
})
}
}

func TestPrepareKey(t *testing.T) {
require.EqualValues(t, "unchanged", prepareKey("unchanged"))
require.EqualValues(t, "sin''gle", prepareKey("sin'gle"))
require.EqualValues(t, "''beginning", prepareKey("'beginning"))
require.EqualValues(t, "end''", prepareKey("end'"))
require.EqualValues(t, "''quoted''", prepareKey("'quoted'"))
require.EqualValues(t, "d''''ouble", prepareKey("d''ouble"))
require.EqualValues(t, "''", prepareKey("'"))
require.EqualValues(t, "", prepareKey(""))
}
26 changes: 13 additions & 13 deletions sdk/data/aztables/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ module github.com/Azure/azure-sdk-for-go/sdk/data/aztables
go 1.18

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0
github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0
github.com/stretchr/testify v1.8.2
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0
github.com/stretchr/testify v1.8.4
)

require (
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dnaeon/go-vcr v1.1.0 // indirect
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
github.com/google/uuid v1.1.1 // indirect
github.com/dnaeon/go-vcr v1.2.0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
65 changes: 28 additions & 37 deletions sdk/data/aztables/go.sum
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 h1:rTnT/Jrcm+figWlYz4Ixzt0SJVR2cMC8lvZcimipiEY=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0 h1:Yoicul8bnVdQrhDMTHxdEckRGX01XvwXDHUT9zYZ3k0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0 h1:leh5DwKv6Ihwi+h60uHtn6UWAxBbZ0q8DwQVMzf61zw=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0 h1:WVsrXCnHlDDX8ls+tootqRE87/hL9S/g4ewig9RsD/c=
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY=
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4 h1:Qj1ukM4GlMWXNdMBuXcXfz/Kw9s1qm0CLY32QxuSImI=
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 h1:Tgea0cVUD0ivh5ADBX4WwuI12DUd2to3nCYe2eayMIw=
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6 changes: 5 additions & 1 deletion sdk/data/aztables/zt_table_recorded_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@ type complexTestEntity struct {
}

func createSimpleEntity(count int, pk string) basicTestEntity {
return createSimpleEntityWithRowKey(count, pk, fmt.Sprint(count))
}

func createSimpleEntityWithRowKey(count int, pk string, rk string) basicTestEntity {
return basicTestEntity{
Entity: Entity{
PartitionKey: pk,
RowKey: fmt.Sprint(count),
RowKey: rk,
},
String: fmt.Sprintf("some string %d", count),
Integer: int32(count),
Expand Down

0 comments on commit 6d3bfc2

Please sign in to comment.