Skip to content

Commit 2b6b275

Browse files
authored
Fix issue with url encoding for request properties with values that have a majority of characters that need to be percent encoded (#3875)
1 parent 76e0438 commit 2b6b275

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"core": {
3+
"updateMinimum": true,
4+
"type": "patch",
5+
"changeLogMessages": [
6+
"Fix issue with url encoding for request properties with values that have a majority of characters that need to be percent encoded"
7+
]
8+
}
9+
}

sdk/src/Core/Amazon.Util/AWSSDKUtils.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,16 +1044,23 @@ public static string UrlEncode(int rfcNumber, string data, bool path)
10441044
var encoding = Encoding.UTF8;
10451045

10461046
var dataByteLength = encoding.GetMaxByteCount(dataAsSpan.Length);
1047-
var encodedByteLength = 2 * dataByteLength;
1047+
1048+
// The dataBuffer byte span will be used to store utf8 bytes of the data be encoded at the end and
1049+
// url encoded at the start of dataBuffer. As the utf8 bytes are iterated and percent encoded at the
1050+
// beginning dataBuffer the utf8 bytes at the end will be overwritten by the percent encoding.
1051+
// The size of the dataBuffer needs to be 3 times the size utf8 max encoding to handle the worst
1052+
// case scenario of every character needing to be percent encoding taking 3 bytes.
1053+
var encodedByteLength = 3 * dataByteLength;
10481054
var dataBuffer = encodedByteLength <= MaxStackLimit
10491055
? stackalloc byte[MaxStackLimit]
10501056
: sharedDataBuffer = ArrayPool<byte>.Shared.Rent(encodedByteLength);
1057+
10511058
// Instead of stack allocating or renting two buffers we use one buffer with at least twice the capacity of the
10521059
// max encoding length. Then store the character data as bytes in the second half reserving the first half of the buffer
10531060
// for the encoded representation.
10541061
var encodingBuffer = dataBuffer.Slice(dataBuffer.Length - dataByteLength);
10551062
var bytesWritten = encoding.GetBytes(dataAsSpan, encodingBuffer);
1056-
1063+
10571064
var index = 0;
10581065
foreach (var symbol in encodingBuffer.Slice(0, bytesWritten))
10591066
{

sdk/test/NetStandard/UnitTests/Core/AWSSDKUtilsTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using Amazon.Util;
33
using System.Text;
44
using Amazon.Runtime.Internal;
@@ -67,6 +67,8 @@ public void DetermineService(string url, string expectedService)
6767
[Theory]
6868
[InlineData("value, with special chars!", "value%2C%20with%20special%20chars%21")]
6969
[InlineData("value, with special chars and path {/+:}", "value%2C%20with%20special%20chars%20and%20path%20%7B%2F%2B%3A%7D")]
70+
[InlineData("紙_一般_児童手当等の受給資格及び児童手当の額についての認定請求公金非対応", "%E7%B4%99_%E4%B8%80%E8%88%AC_%E5%85%90%E7%AB%A5%E6%89%8B%E5%BD%93%E7%AD%89%E3%81%AE%E5%8F%97%E7%B5%A6%E8%B3%87%E6%A0%BC%E5%8F%8A%E3%81%B3%E5%85%90%E7%AB%A5%E6%89%8B%E5%BD%93%E3%81%AE%E9%A1%8D%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E8%AA%8D%E5%AE%9A%E8%AB%8B%E6%B1%82%E5%85%AC%E9%87%91%E9%9D%9E%E5%AF%BE%E5%BF%9C")]
71+
7072
public void UrlEncodeWithoutPath(string input, string expected)
7173
{
7274
var encoded = AWSSDKUtils.UrlEncode(input, path: false);
@@ -78,6 +80,7 @@ public void UrlEncodeWithoutPath(string input, string expected)
7880
[InlineData("\ud83d\ude02 value, with special chars!", "%F0%9F%98%82%20value,%20with%20special%20chars!")]
7981
[InlineData("value, with special chars!", "value,%20with%20special%20chars!")]
8082
[InlineData("value, with special chars and path {/+:}", "value,%20with%20special%20chars%20and%20path%20%7B/+%3A%7D")]
83+
[InlineData("紙_一般_児童手当等の受給資格及び児童手当の額についての認定請求公金非対応", "%E7%B4%99_%E4%B8%80%E8%88%AC_%E5%85%90%E7%AB%A5%E6%89%8B%E5%BD%93%E7%AD%89%E3%81%AE%E5%8F%97%E7%B5%A6%E8%B3%87%E6%A0%BC%E5%8F%8A%E3%81%B3%E5%85%90%E7%AB%A5%E6%89%8B%E5%BD%93%E3%81%AE%E9%A1%8D%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E8%AA%8D%E5%AE%9A%E8%AB%8B%E6%B1%82%E5%85%AC%E9%87%91%E9%9D%9E%E5%AF%BE%E5%BF%9C")]
8184
public void UrlEncodeWithPath(string input, string expected)
8285
{
8386
var encoded = AWSSDKUtils.UrlEncode(input, path: true);

0 commit comments

Comments
 (0)