Skip to content

Commit 77752a0

Browse files
committed
Fix gist search term encoding
1 parent 7857ce6 commit 77752a0

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

GitRekt.Tests/SourcesTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,22 @@ public void ExtractGistSearchTerms_DropsAdvancedQualifiers()
8787
Assert.Equal(["Password1", "token"], terms);
8888
}
8989

90+
[Fact]
91+
public void ExtractGistSearchTerms_SplitsSimplePunctuationLikeGitHubSearch()
92+
{
93+
var terms = GithubClient.ExtractGistSearchTerms("Password:", useAdvancedQuery: false);
94+
95+
Assert.Equal(["Password"], terms);
96+
}
97+
98+
[Fact]
99+
public void ExtractGistSearchTerms_KeepsDomainLikeSimpleTerms()
100+
{
101+
var terms = GithubClient.ExtractGistSearchTerms("ghd.com", useAdvancedQuery: false);
102+
103+
Assert.Equal(["ghd.com"], terms);
104+
}
105+
90106
[Fact]
91107
public async Task SearchGistPagesAsync_UsesGistSearchAndResolvesLineNumbers()
92108
{

GitRekt/GithubClient.cs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ internal sealed class GithubClient : IDisposable
1616
private const int MaxGistSearchResults = 1000;
1717
private const int MaxGistSnippetLength = 500;
1818
private const long MaxGistRawFileSizeBytes = 10 * 1024 * 1024;
19+
private static readonly char[] GistSearchBoundaryPunctuation = ['"', '\'', '`', ',', ';', ':', '/', '\\', '*', '!', '?', '#', '$', '&', '+', '^', '|', '~', '<', '>', '(', ')', '{', '}', '[', ']'];
1920
private static readonly TimeSpan MaxAutomaticRateLimitDelay = TimeSpan.FromMinutes(1);
2021
private const int MaxAutomaticRateLimitRetries = 3;
2122
private static readonly TimeSpan SecondaryRateLimitDelay = TimeSpan.FromSeconds(15);
@@ -413,10 +414,7 @@ internal static IReadOnlyList<string> ExtractGistSearchTerms(string query, bool
413414

414415
if (!useAdvancedQuery)
415416
{
416-
return query
417-
.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
418-
.Distinct(StringComparer.OrdinalIgnoreCase)
419-
.ToList();
417+
return ExtractSimpleGistSearchTerms(query);
420418
}
421419

422420
var terms = new List<string>();
@@ -459,6 +457,47 @@ internal static IReadOnlyList<string> ExtractGistSearchTerms(string query, bool
459457
.ToList();
460458
}
461459

460+
private static IReadOnlyList<string> ExtractSimpleGistSearchTerms(string query)
461+
{
462+
var terms = new List<string>();
463+
var tokens = query.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
464+
465+
foreach (var token in tokens)
466+
{
467+
var trimmedToken = token.Trim();
468+
469+
if (string.IsNullOrWhiteSpace(trimmedToken))
470+
{
471+
continue;
472+
}
473+
474+
if (LooksLikeDomainOrHost(trimmedToken))
475+
{
476+
terms.Add(trimmedToken.Trim(GistSearchBoundaryPunctuation));
477+
continue;
478+
}
479+
480+
terms.AddRange(Regex.Split(trimmedToken, @"[\s\\.,:;/`'""=\*!?\#\$&\+\^\|~<>\(\)\{\}\[\]]+")
481+
.Select(term => term.Trim())
482+
.Where(term => !string.IsNullOrWhiteSpace(term)));
483+
}
484+
485+
return terms
486+
.Where(term => !string.IsNullOrWhiteSpace(term))
487+
.Distinct(StringComparer.OrdinalIgnoreCase)
488+
.ToList();
489+
}
490+
491+
private static bool LooksLikeDomainOrHost(string token)
492+
{
493+
var trimmedToken = token.Trim(GistSearchBoundaryPunctuation);
494+
495+
return Regex.IsMatch(
496+
trimmedToken,
497+
@"\A(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\z",
498+
RegexOptions.CultureInvariant);
499+
}
500+
462501
internal static int CountLinesBeforeIndex(string content, int index)
463502
{
464503
var lineCount = 0;

0 commit comments

Comments
 (0)