Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
37cf846
Update codeql-analysis.yml
rathimayur Dec 23, 2025
50a8dee
Merge pull request #4399 from Ginger-Automation/Add-JavaScript-for-se…
ravirk91 Dec 23, 2025
fb78ef0
Merge branch 'master' into merge-official-to-master
ravirk91 Dec 29, 2025
a8ea7cb
Merge pull request #4405 from Ginger-Automation/merge-official-to-master
ravirk91 Dec 29, 2025
4b05581
Rollbacked the changes made for handling the file name length
shahanemahesh Jan 7, 2026
97bdccb
Merge branch 'master' into Issue_57908
shahanemahesh Jan 7, 2026
3b78809
Modified code to support maxlength only for folder name
shahanemahesh Jan 9, 2026
cb1a99b
Merge branch 'Issue_57908' of https://github.com/Ginger-Automation/Gi…
shahanemahesh Jan 9, 2026
c673073
Merge pull request #4407 from Ginger-Automation/Issue_57908
shahanemahesh Jan 12, 2026
e5b289d
Removed the task implementation in unix agent
shahanemahesh Jan 15, 2026
e053f09
Merge pull request #4409 from Ginger-Automation/Issue_58103
ravirk91 Jan 16, 2026
7614a61
Fixed issue of special characters from toerh languages are not gettin…
shahanemahesh Jan 16, 2026
5e6d4ab
Merge branch 'master' into Issue_57144
shahanemahesh Jan 19, 2026
c9d1dce
Merge pull request #4412 from Ginger-Automation/Issue_57144
ravirk91 Jan 21, 2026
e475266
Shared Repository Folder View (#4416)
AmanPrasad43 Jan 22, 2026
3371926
Master for beta merge (#4429)
ravirk91 Feb 3, 2026
242601d
Prevent Excel formula injection in CSV export (#4431)
tanushahande2003 Feb 5, 2026
967906e
added an option to change text color in consoleDriver window
omri1911 Feb 8, 2026
f124c1d
Action Description fix (#4434)
AmanPrasad43 Feb 10, 2026
0c4ea8d
Update to .NET 10, package versions, and minor UI tweaks (#4435)
tanushahande2003 Feb 13, 2026
e043d8f
Mask API key in UI and update only on user edit (#4436)
tanushahande2003 Feb 17, 2026
4c34712
Merge branch 'master' into Feature/ColorSelectionOnConsoleDriver
ravirk91 Feb 17, 2026
e9d7304
Merge pull request #4433 from Ginger-Automation/Feature/ColorSelectio…
shahanemahesh Feb 17, 2026
046e1b8
Fix codeql-config.yml file place
NadeemJazmawe Feb 17, 2026
343d439
Upgrade Github Actions versions
NadeemJazmawe Feb 17, 2026
ab1b3ae
Merge pull request #4439 from Ginger-Automation/Upgrade_GitHub_Actions
NadeemJazmawe Feb 17, 2026
169e9f1
Update license headers to 2026 and add missing headers (#4440)
tanushahande2003 Feb 19, 2026
e7ed02c
Register serializer classes earlier; null check in IsReady (#4441)
ravirk91 Feb 20, 2026
71eb5ee
Downgrade LibGit2Sharp.NativeBinaries to 2.0.278 (#4442)
tanushahande2003 Feb 20, 2026
bbf224b
Updated the SSH and Cryptography nuget package to latest (#4432)
shahanemahesh Feb 20, 2026
f225bab
contract update for pipeline run description (#4437)
AmanPrasad43 Feb 20, 2026
118ecdb
Added Code to allow Solution File to be loaded using SolutionReposito…
rathimayur Feb 20, 2026
a7010ff
Refactor export query generation and persistence logic (#4447)
tanushahande2003 Feb 27, 2026
36ca9f1
Updated to latest version of Magick.NET nuget due to vulnarability de…
rathimayur Mar 3, 2026
0284e27
Merge 2026.3 to master (#4457)
ravirk91 Mar 9, 2026
dea527e
Selenium upgrade (#4461)
AmanPrasad43 Mar 11, 2026
6f5e65a
Add explicit Android TV handling for unsupported actions (#4462)
tanushahande2003 Mar 11, 2026
6651ddb
ssh downgrade (#4464)
AmanPrasad43 Mar 12, 2026
dabb7f9
Update Magick.NET and MimeKit package versions (#4465)
tanushahande2003 Mar 16, 2026
b29bce8
Update AutoMapper to 16.1.1 and add LoggerFactory support (#4468)
tanushahande2003 Mar 17, 2026
4921559
Improve password variable handling and reset logic (#4470)
tanushahande2003 Mar 20, 2026
35d543d
Update Magick.NET-Q16-AnyCPU to version 14.11.1 (#4473)
tanushahande2003 Mar 25, 2026
0ea14c4
Add VE button to Path column in XML Tag Validation grid (#4471)
tanushahande2003 Mar 26, 2026
4a81282
Feature/uft lab app selection (#4472)
omri1911 Mar 30, 2026
024a94e
upgraded the ginger execution report for mail to have a more modern d…
omri1911 Mar 31, 2026
8556808
Merge official to master (#4485)
ravirk91 Apr 13, 2026
2cc0107
Increase folder name limit to 255 chars in report configs (#4486)
tanushahande2003 Apr 23, 2026
bccf642
Update Magick.NET-Q16-AnyCPU to v14.13.0 in all projects (#4487)
tanushahande2003 Apr 29, 2026
42a8a28
Improve JSON handling and HTML encoding in API helpers (#4489)
tanushahande2003 Apr 29, 2026
29052ac
Parse SslMode from connection string for MySQL (#4488)
tanushahande2003 Apr 29, 2026
049b738
Potential fix for code scanning alert no. 560: Cross-site scripting (…
ravirk91 Apr 29, 2026
c626a3b
Merge branch 'Releases/Official-Release' into Merge-master-to-officia…
ravirk91 May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="App type:" Style="{StaticResource $LabelStyle}" VerticalAlignment="Center" />
<RadioButton x:Name="xNativeHybRdBtn" Content="Native/Hybrid" Style="{StaticResource $InputRadioButtonStyle}" GroupName="AppType" VerticalAlignment="Center" Margin="8,0,0,0" IsChecked="True" Checked="ActivityTypeSelectionChanged"/>
<RadioButton x:Name="xNativeHybRdBtn" Content="Native/Hybrid" Style="{StaticResource $InputRadioButtonStyle}" GroupName="AppType" VerticalAlignment="Center" Margin="36,0,0,0" IsChecked="True" Checked="ActivityTypeSelectionChanged"/>
<RadioButton x:Name="xWebRdBtn" Content="Web" Style="{StaticResource $InputRadioButtonStyle}" GroupName="AppType" VerticalAlignment="Center" Margin="7,0,0,0" Checked="ActivityTypeSelectionChanged"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
Expand Down
3 changes: 0 additions & 3 deletions Ginger/Ginger/Environments/AppsListPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ private void SetGridView()
new GridColView() { Field = nameof(EnvApplication.Url), WidthWeight = 100, Header = "URL" },
]
};

grdApps.SetAllColumnsDefaultView(view);
grdApps.InitViewItems();
}

private void SetGridData()
Expand Down
2 changes: 1 addition & 1 deletion Ginger/Ginger/Ginger.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@
<PackageReference Include="LiteDB" Version="5.0.21" />
<PackageReference Include="LiveCharts.Wpf.NetCore3" Version="0.9.8" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.11.1" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.13.0" />
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="10.3.0" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.15.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.15.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ private void OkButton_Click(object sender, RoutedEventArgs e)
Reporter.ToUser(eUserMsgKey.FolderNameTextBoxIsEmpty);
return;
}
else if (extraInformationCalculated.Length > 100)
else if (extraInformationCalculated.Length > 255)
{
Reporter.ToUser(eUserMsgKey.FolderNamesAreTooLong);
Reporter.ToUser(eUserMsgKey.FolderPathsAreTooLong);
return;
}
}
Expand Down
3 changes: 2 additions & 1 deletion Ginger/GingerCoreCommon/ReporterLib/UserMsgsPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public enum eUserMsgKey
ActivitiesGroupAlreadyMappedToTC, ExportItemToALMFailed, AskIfToSaveBFAfterExport, ALMIncorrectExternalID,
BusinessFlowAlreadyMappedToTC, AskIfSureWantToClose, AskIfSureWantToCloseWithoutNote, AskIfSureWantToRestart, AskIfSureWantToRestartWithoutNote, AskIfSureWantToRestartInAdminMode, WindowClosed, TargetWindowNotSelected,
ChangingEnvironmentParameterValue, IFSaveChangesOfBF, AskIfToLoadExternalFields, WhetherToOpenSolution,
AutomationTabExecResultsNotExists, FolderNamesAreTooLong, FolderSizeTooSmall, DefaultTemplateCantBeDeleted, FileNotExist, ExecutionsResultsProdIsNotOn, ExecutionsResultsNotExists, ExecutionsResultsToDelete, AllExecutionsResultsToDelete, FilterNotBeenSet, RetreivingAllElements, ClickElementAgain, CloseFilterPage,
AutomationTabExecResultsNotExists, FolderNamesAreTooLong, FolderPathsAreTooLong, FolderSizeTooSmall, DefaultTemplateCantBeDeleted, FileNotExist, ExecutionsResultsProdIsNotOn, ExecutionsResultsNotExists, ExecutionsResultsToDelete, AllExecutionsResultsToDelete, FilterNotBeenSet, RetreivingAllElements, ClickElementAgain, CloseFilterPage,
BusinessFlowNeedTargetApplication, HTMLReportAttachment, ImageSize, ImageSizeTill5Mb,
GherkinAskToSaveFeatureFile, GherkinScenariosGenerated, GherkinNotifyFeatureFileExists, GherkinNotifyFeatureFileSelectedFromTheSolution, GherkinNotifyBFIsNotExistForThisFeatureFile, GherkinFileNotFound, GherkinColumnNotExist, GherkinActivityNotFound, GherkinBusinessFlowNotCreated, GherkinFeatureFileImportedSuccessfully, GherkinFeatureFileImportOnlyFeatureFileAllowedErrorMessage,
AskIfSureWantToDeLink, AnalyzerFoundIssues, AnalyzerFoundNoIssues, AnalyzerSaveRunSet,
Expand Down Expand Up @@ -616,6 +616,7 @@ public static void LoadUserMsgsPool()
{ eUserMsgKey.ReportTemplateNotFound, new UserMsg(eUserMsgType.ERROR, "Report Template", "Report Template '{0}' not found", eUserMsgOption.OK, eUserMsgSelection.None) },
{ eUserMsgKey.AutomationTabExecResultsNotExists, new UserMsg(eUserMsgType.WARN, "Execution Results are not existing", "Results from last execution are not existing (yet). Nothing to report, please wait for execution finish and click on report creation.", eUserMsgOption.OK, eUserMsgSelection.None) },
{ eUserMsgKey.FolderNamesAreTooLong, new UserMsg(eUserMsgType.WARN, "Folders Names Are Too Long", "Provided folders names are too long. Please change them to be less than 100 characters", eUserMsgOption.OK, eUserMsgSelection.None) },
{ eUserMsgKey.FolderPathsAreTooLong, new UserMsg(eUserMsgType.WARN, "Folder Paths Are Too Long", "Provided folder paths are too long. Please change them to be less than 255 characters", eUserMsgOption.OK, eUserMsgSelection.None) },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

User-facing message text is inaccurate — "less than 255" conflicts with the > 255 guard.

The validation in HTMLReportAttachmentConfigurationPage.xaml.cs fires when Length > 255, meaning a path of exactly 255 characters is valid. The current message text tells users to keep paths "less than 255 characters", which incorrectly implies 254 is the maximum.

✏️ Suggested fix
-{ eUserMsgKey.FolderPathsAreTooLong, new UserMsg(eUserMsgType.WARN, "Folder Paths Are Too Long", "Provided folder paths are too long. Please change them to be less than 255 characters", eUserMsgOption.OK, eUserMsgSelection.None) },
+{ eUserMsgKey.FolderPathsAreTooLong, new UserMsg(eUserMsgType.WARN, "Folder Paths Are Too Long", "Provided folder paths are too long. Please change them to be no more than 255 characters", eUserMsgOption.OK, eUserMsgSelection.None) },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ eUserMsgKey.FolderPathsAreTooLong, new UserMsg(eUserMsgType.WARN, "Folder Paths Are Too Long", "Provided folder paths are too long. Please change them to be less than 255 characters", eUserMsgOption.OK, eUserMsgSelection.None) },
{ eUserMsgKey.FolderPathsAreTooLong, new UserMsg(eUserMsgType.WARN, "Folder Paths Are Too Long", "Provided folder paths are too long. Please change them to be no more than 255 characters", eUserMsgOption.OK, eUserMsgSelection.None) },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Ginger/GingerCoreCommon/ReporterLib/UserMsgsPool.cs` at line 619, The
user-facing message for eUserMsgKey.FolderPathsAreTooLong in UserMsgsPool.cs
contradicts the validation (which allows length == 255 and flags > 255); update
the message string in the UserMsg constructor (the entry keyed by
eUserMsgKey.FolderPathsAreTooLong) to say something like "Provided folder paths
are too long. Please change them to be 255 characters or less" (or "no more than
255 characters") so it matches the > 255 guard.

{ eUserMsgKey.FolderSizeTooSmall, new UserMsg(eUserMsgType.WARN, "Folders Size is Too Small", "Provided folder size is Too Small. Please change it to be bigger than 50 Mb", eUserMsgOption.OK, eUserMsgSelection.None) },
{ eUserMsgKey.DefaultTemplateCantBeDeleted, new UserMsg(eUserMsgType.WARN, "Default Template Can't Be Deleted", "Default Template Can't Be Deleted. Please change it to be a non-default", eUserMsgOption.OK, eUserMsgSelection.None) },
{ eUserMsgKey.ExecutionsResultsProdIsNotOn, new UserMsg(eUserMsgType.WARN, "Executions Results Producing Should Be Switched On", "In order to perform this action, executions results producing should be switched On", eUserMsgOption.OK, eUserMsgSelection.None) },
Expand Down
29 changes: 28 additions & 1 deletion Ginger/GingerCoreNET/Database/DatabaseOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,34 @@ public Boolean Connect(bool displayErrorPopup = false)
Password = EncryptionHandler.DecryptwithKey(PassCalculated)
};
if (port1.HasValue) my.Port = port1.Value;
Database.ConnectionString = my.ConnectionString;
if (!string.IsNullOrEmpty(ConnectionStringCalculated))
{
foreach (string segment in ConnectionStringCalculated.Split(';', StringSplitOptions.RemoveEmptyEntries))
{
int eq = segment.IndexOf('=');
if (eq <= 0)
{
continue;
}

string key = segment.Substring(0, eq).Trim();
if (key.Equals("SslMode", StringComparison.OrdinalIgnoreCase))
{
string value = segment.Substring(eq + 1).Trim();
if (Enum.TryParse(value, ignoreCase: true, out MySqlSslMode sslMode))
{
my.SslMode = sslMode;
}

break;
}
}
}

if (string.IsNullOrEmpty(ConnectionStringCalculated))
{
Database.ConnectionString = my.ConnectionString;
}

oConn = new MySqlConnection
{
Expand Down
32 changes: 29 additions & 3 deletions Ginger/GingerCoreNET/External/WireMock/WireMockAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ limitations under the License.
using Amdocs.Ginger.Common;
using Amdocs.Ginger.Common.External.Configurations;
using System;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Amdocs.Ginger.CoreNET.External.WireMock
Expand Down Expand Up @@ -99,7 +101,8 @@ public async Task<string> StartRecordingAsync(string targetUrl)

using (HttpClient client = new HttpClient())
{
var content = new StringContent($"{{\"targetBaseUrl\": \"{targetUrl}\"}}", Encoding.UTF8, "application/json");
string json = JsonSerializer.Serialize(new { targetBaseUrl = targetUrl });
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync($"{NormalizeUrl(GingerCore.ValueExpression.PasswordCalculation(_baseUrl))}{StartRecordingEndpoint}", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
Expand Down Expand Up @@ -153,7 +156,19 @@ public async Task<string> CreateStubAsync(string stubMapping, string contentType
{
contentType = "application/json";
}
var content = new StringContent(stubMapping, Encoding.UTF8, contentType);

string body;
if (string.IsNullOrEmpty(stubMapping))
{
body = stubMapping;
}
else
{
using JsonDocument doc = JsonDocument.Parse(stubMapping);
body = doc.RootElement.GetRawText();
}

var content = new StringContent(WebUtility.HtmlEncode(body), Encoding.UTF8, contentType);
Comment on lines +160 to +171
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In .NET, what does new StringContent((string)null, Encoding.UTF8, "application/json")do, and shouldWebUtility.HtmlEncodebe used on JSON bodies sent asapplication/json?

💡 Result:

The expression new StringContent((string)null, Encoding.UTF8, "application/json") creates a StringContent instance intended to represent a null string value in the HTTP request body, with UTF-8 encoding and Content-Type header set to "application/json" [1][2][3]. In modern.NET versions (e.g.,.NET 8+ as of 2026), the constructor explicitly throws ArgumentNullException if the content string is null, as shown in the source code: ArgumentNullException.ThrowIfNull(content); before encoding [1]. This distinguishes null from empty string (which is allowed and sends an empty body). Earlier versions may have allowed it, treating null differently [4]. WebUtility.HtmlEncode should not be used on JSON bodies sent as application/json [5][6]. WebUtility.HtmlEncode converts special characters like < > " to HTML entities for safe insertion into HTML contexts [5]. JSON is a distinct format parsed directly by servers/clients based on Content-Type; HTML encoding corrupts valid JSON (e.g., "{"key": ""}" becomes invalid after encoding), causing parse errors [7][8]. JSON serializers handle escaping (e.g., \u003c for < in strings) as needed. Use it only for HTML output, not JSON payloads [6].

Citations:


🏁 Script executed:

cat -n Ginger/GingerCoreNET/External/WireMock/WireMockAPI.cs | sed -n '150,180p'

Repository: Ginger-Automation/Ginger

Length of output: 1628


🏁 Script executed:

cat -n Ginger/GingerCoreNET/External/WireMock/WireMockAPI.cs | sed -n '215,240p'

Repository: Ginger-Automation/Ginger

Length of output: 1338


🏁 Script executed:

head -30 Ginger/GingerCoreNET/External/WireMock/WireMockAPI.cs | cat -n

Repository: Ginger-Automation/Ginger

Length of output: 1181


Fix stub payload construction: null-safe content and no HTML encoding for JSON.

There are two correctness issues:

  1. Lines 161-164 and 223-226 assign body = stubMapping when stubMapping is null/empty, causing new StringContent(null, ...) to throw ArgumentNullException at runtime.
  2. Line 171 HTML-encodes the JSON body before sending as application/json, which corrupts valid JSON (e.g., " becomes &quot;).
Suggested fix
-                    string body;
-                    if (string.IsNullOrEmpty(stubMapping))
-                    {
-                        body = stubMapping;
-                    }
-                    else
-                    {
-                        using JsonDocument doc = JsonDocument.Parse(stubMapping);
-                        body = doc.RootElement.GetRawText();
-                    }
-
-                    var content = new StringContent(WebUtility.HtmlEncode(body), Encoding.UTF8, contentType);
+                    string body = string.IsNullOrWhiteSpace(stubMapping)
+                        ? string.Empty
+                        : JsonDocument.Parse(stubMapping).RootElement.GetRawText();
+
+                    var content = new StringContent(body, Encoding.UTF8, contentType);
@@
-                    string body;
-                    if (string.IsNullOrEmpty(stubMapping))
-                    {
-                        body = stubMapping;
-                    }
-                    else
-                    {
-                        using JsonDocument doc = JsonDocument.Parse(stubMapping);
-                        body = doc.RootElement.GetRawText();
-                    }
+                    string body = string.IsNullOrWhiteSpace(stubMapping)
+                        ? string.Empty
+                        : JsonDocument.Parse(stubMapping).RootElement.GetRawText();

Also applies to: 222-233

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Ginger/GingerCoreNET/External/WireMock/WireMockAPI.cs` around lines 160 -
171, The stub payload construction is not null-safe and incorrectly HTML-encodes
JSON; change the logic around stubMapping/body so you never pass null into new
StringContent (use empty string or "{}" as appropriate) and remove
WebUtility.HtmlEncode so the JSON is sent raw; update the block that parses
stubMapping (the JsonDocument.Parse branch and the fallback) and the
StringContent creation (the call to new StringContent(..., Encoding.UTF8,
contentType)) to use the non-null raw JSON string instead of HtmlEncoded data.

HttpResponseMessage response = await client.PostAsync($"{NormalizeUrl(GingerCore.ValueExpression.PasswordCalculation(_baseUrl))}{MappingEndpoint}", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
Expand Down Expand Up @@ -204,7 +219,18 @@ public async Task<string> UpdateStubAsync(string stubId, string stubMapping)

using (HttpClient client = new HttpClient())
{
var content = new StringContent(stubMapping, Encoding.UTF8, "application/json");
string body;
if (string.IsNullOrEmpty(stubMapping))
{
body = stubMapping;
}
else
{
using JsonDocument doc = JsonDocument.Parse(stubMapping);
body = doc.RootElement.GetRawText();
}

var content = new StringContent(body, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PutAsync($"{NormalizeUrl(GingerCore.ValueExpression.PasswordCalculation(_baseUrl))}{MappingEndpoint}/{stubId}", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
Expand Down
14 changes: 7 additions & 7 deletions Ginger/GingerCoreNET/GenAIServices/GenAIServiceHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ limitations under the License.
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

Expand Down Expand Up @@ -104,8 +105,7 @@ private async Task<bool> GetToken()
catch (Exception ex)
{
var error = "Failed to get access token";
Reporter.ToLog(eLogLevel.ERROR, $"{error}, Error :{ex.Message}");
Reporter.ToLog(eLogLevel.ERROR, $"{error}, Error :{ex.Message}, InnerException:{ex.InnerException},StackTrace:{ex.StackTrace}");
Reporter.ToLog(eLogLevel.ERROR, error, ex);
return false;
Comment on lines 107 to 109
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the standard error-logging signature in this catch block.

Line 108 uses Reporter.ToLog(eLogLevel.ERROR, error, ex), but this repository requires the message-only overload for error logs.

Suggested fix
-                var error = "Failed to get access token";
-                Reporter.ToLog(eLogLevel.ERROR, error, ex);
+                var error = $"Failed to get access token. {ex.Message}";
+                Reporter.ToLog(eLogLevel.ERROR, error);

As per coding guidelines **/*.cs: Use Reporter.ToLog(eLogLevel.ERROR, message) for logging errors.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var error = "Failed to get access token";
Reporter.ToLog(eLogLevel.ERROR, $"{error}, Error :{ex.Message}");
Reporter.ToLog(eLogLevel.ERROR, $"{error}, Error :{ex.Message}, InnerException:{ex.InnerException},StackTrace:{ex.StackTrace}");
Reporter.ToLog(eLogLevel.ERROR, error, ex);
return false;
var error = $"Failed to get access token. {ex.Message}";
Reporter.ToLog(eLogLevel.ERROR, error);
return false;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Ginger/GingerCoreNET/GenAIServices/GenAIServiceHelper.cs` around lines 107 -
109, In GenAIServiceHelper.cs update the catch block that currently sets var
error = "Failed to get access token" and calls Reporter.ToLog(eLogLevel.ERROR,
error, ex): replace the three-argument call with the repository-required
message-only overload Reporter.ToLog(eLogLevel.ERROR, error) (leave the error
string and exception handling intact but remove passing ex to Reporter.ToLog) so
the code uses the standard logging signature used across this codebase.

}
}
Expand Down Expand Up @@ -245,11 +245,11 @@ private MultipartFormDataContent PrepareRequestDetailsForChat(string Question)
var content = new MultipartFormDataContent
{
{ new StringContent(Question), "question" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.Account)), "account" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DomainType)), "domainType" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.TemperatureLevel)), "temperatureVal" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.MaxTokenValue)), "maxTokensVal" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DataPath)), "dataPath" }
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.Account) ?? string.Empty)), "account" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DomainType) ?? string.Empty)), "domainType" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.TemperatureLevel) ?? string.Empty)), "temperatureVal" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.MaxTokenValue) ?? string.Empty)), "maxTokensVal" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DataPath) ?? string.Empty)), "dataPath" }
Comment on lines +248 to +252
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In .NET, is System.Net.WebUtility.HtmlEncodeappropriate for values sent throughMultipartFormDataContent/StringContent, or is it intended only for HTML output encoding?

💡 Result:

Answer: No—System.Net.WebUtility.HtmlEncode is not the appropriate encoding step for values you put into MultipartFormDataContent/StringContent as general “HTTP/form data escaping”. It’s intended for HTML entity encoding (and its docs even describe HTML encoding behavior), not for making arbitrary multipart/form-data fields safe to transmit. For multipart form values, you should generally send the raw string (letting StringContent handle HTTP body bytes/charset) and only apply encoding appropriate to the receiving context (e.g., HTML-escape only when inserting into HTML, URL-encode only for URL/query-string components). Why: 1) WebUtility.HtmlEncode is defined as converting a string into an HTML-encoded string (HTML entities), including a remark that encoding converts characters into “character-entity equivalents” and gives < and > as examples for HTTP transmission when embedded in text/HTML blocks. That describes HTML entity encoding, not multipart/form-data field escaping rules [1]. 2) MultipartFormDataContent is a container for content encoded using the multipart/form-data MIME type. It “adds required Content-Disposition headers to [the] content object added to the collection” and serializes the multipart stream. It does not state that callers should pre–HTML-encode field values [2]. 3) If you HTML-encode form fields, you can change the payload semantics: e.g., a value containing & becomes &amp;, and the server will receive &amp; unless it explicitly HTML-decodes it. Multipart/form-data processing is governed by MIME/form encoding rules (e.g., how parts are structured and how headers like Content-Disposition are represented), not by HTML entity encoding. Practical guidance: - For MultipartFormDataContent fields, typically do: form.Add(new StringContent(value, Encoding.UTF8), "name"); and avoid HTML-encoding unless the server expects HTML entities. - Apply encoding at the “output to HTML” step: if (and only if) the server later renders the submitted value into an HTML page, then HTML encoding should happen right before HTML rendering. So: WebUtility.HtmlEncode is primarily an HTML entity encoder, not a general-purpose “safe for HTTP form data/multipart” encoder.

Citations:


Remove WebUtility.HtmlEncode() from multipart form field values.

Lines 248-252 apply WebUtility.HtmlEncode(...) before StringContent. HtmlEncode is intended for HTML entity encoding only and is inappropriate for form-data payloads. It mutates field values (e.g., & becomes &amp;), which can break backend parsing and value matching. For MultipartFormDataContent, send raw string values directly.

Suggested fix
-                { new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.Account) ?? string.Empty)), "account" },
-                { new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DomainType) ?? string.Empty)), "domainType" },
-                { new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.TemperatureLevel) ?? string.Empty)), "temperatureVal" },
-                { new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.MaxTokenValue) ?? string.Empty)), "maxTokensVal" },
-                { new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DataPath) ?? string.Empty)), "dataPath" }
+                { new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.Account) ?? string.Empty), "account" },
+                { new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DomainType) ?? string.Empty), "domainType" },
+                { new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.TemperatureLevel) ?? string.Empty), "temperatureVal" },
+                { new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.MaxTokenValue) ?? string.Empty), "maxTokensVal" },
+                { new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DataPath) ?? string.Empty), "dataPath" }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.Account) ?? string.Empty)), "account" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DomainType) ?? string.Empty)), "domainType" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.TemperatureLevel) ?? string.Empty)), "temperatureVal" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.MaxTokenValue) ?? string.Empty)), "maxTokensVal" },
{ new StringContent(WebUtility.HtmlEncode(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DataPath) ?? string.Empty)), "dataPath" }
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.Account) ?? string.Empty), "account" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DomainType) ?? string.Empty), "domainType" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.TemperatureLevel) ?? string.Empty), "temperatureVal" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.MaxTokenValue) ?? string.Empty), "maxTokensVal" },
{ new StringContent(CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration.DataPath) ?? string.Empty), "dataPath" }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Ginger/GingerCoreNET/GenAIServices/GenAIServiceHelper.cs` around lines 248 -
252, The multipart form field values are being HTML-encoded before being wrapped
in StringContent in GenAIServiceHelper.cs; remove the WebUtility.HtmlEncode(...)
calls so the raw results of
CredentialsCalculation(WorkSpace.Instance.Solution.AskLisaConfiguration....) are
passed directly into the StringContent for the fields "account", "domainType",
"temperatureVal", "maxTokensVal" and "dataPath"; keep using
CredentialsCalculation and StringContent but do not mutate the values with
HtmlEncode when building the MultipartFormDataContent.

};
return content;
}
Expand Down
2 changes: 1 addition & 1 deletion Ginger/GingerCoreNET/GingerCoreNET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@

<PackageReference Include="log4net" Version="2.0.15" />

<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.11.1" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.13.0" />

<PackageReference Include="MailKit" Version="4.14.1" />

Expand Down
2 changes: 1 addition & 1 deletion Ginger/GingerTest/GingerTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<PackageReference Include="Ginger.ExecuterService.Contracts" Version="2026.3.0" />
<PackageReference Include="GingerTestHelper" Version="2.0.2" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.11.1" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="14.13.0" />
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.15.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="8.15.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
Expand Down
Loading