Skip to content

Commit f95c007

Browse files
committed
PR feedback and safer max length calculation.
1 parent daa8eb2 commit f95c007

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

src/Elasticsearch.Net/Extensions/NameValueCollectionExtensions.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ internal static string ToQueryString(this NameValueCollection nv)
2222
var maxLength = 1 + nv.AllKeys.Length - 1; // account for '?', and any required '&' chars
2323
foreach (var key in nv.AllKeys)
2424
{
25-
maxLength += 1 + (key.Length + nv[key]?.Length ?? 0) * 3; // '=' char + worst case assume all key/value chars are escaped
25+
var bytes = Encoding.UTF8.GetByteCount(key) + Encoding.UTF8.GetByteCount(nv[key] ?? string.Empty);
26+
var maxEncodedSize = bytes * 3; // worst case, assume all bytes are URL escaped to 3 chars
27+
maxLength += 1 + maxEncodedSize; // '=' + encoded chars
2628
}
2729

2830
// prefer stack allocated array for short lengths
2931
// note: renting for larger lengths is slightly more efficient since no zeroing occurs
3032
char[] rentedFromPool = null;
3133
var buffer = maxLength > MaxCharsOnStack
3234
? rentedFromPool = ArrayPool<char>.Shared.Rent(maxLength)
33-
: stackalloc char[MaxCharsOnStack];
35+
: stackalloc char[maxLength];
3436

3537
try
3638
{

tests/Tests/Extensions/NameValueCollectionExtensionsTests.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,17 @@ public class NameValueCollectionExtensionsTests
3131
new object[] { new NameValueCollection
3232
{
3333
{ "q", null },
34-
}, "?q" }
34+
}, "?q" },
35+
36+
new object[] { new NameValueCollection
37+
{
38+
{ "emoji", "😅"}
39+
}, "?emoji=%F0%9F%98%85" },
40+
41+
new object[] { new NameValueCollection
42+
{
43+
{ "€", "€"}
44+
}, "?%E2%82%AC=%E2%82%AC" }
3545
};
3646
}
3747
}

0 commit comments

Comments
 (0)