Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
2 changes: 1 addition & 1 deletion src/Kiota.Builder/KiotaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2082,7 +2082,7 @@ private static void SetEnumOptions(IOpenApiSchema schema, CodeEnum target)
SerializationName = x,
Documentation = new()
{
DescriptionTemplate = optionDescription?.Description ?? string.Empty,
DescriptionTemplate = optionDescription?.Description?.CleanupDescription() ?? string.Empty,
},
};
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ public override string GetTypeString(CodeTypeBase code, CodeElement targetElemen
throw new InvalidOperationException($"type of type {code.GetType()} is unknown");
}
#pragma warning restore CA1822 // Method should be static
internal static string RemoveInvalidDescriptionCharacters(string originalDescription) => originalDescription.Replace("\\", "/", StringComparison.OrdinalIgnoreCase).Replace("\"\"\"", "\\\"\\\"\\\"", StringComparison.OrdinalIgnoreCase);
internal static string RemoveInvalidDescriptionCharacters(string originalDescription) =>
string.IsNullOrEmpty(originalDescription) ? string.Empty :
originalDescription.Replace("\\", "/", StringComparison.OrdinalIgnoreCase)
.Replace("\t", " ", StringComparison.OrdinalIgnoreCase)
.Replace("\r", " ", StringComparison.OrdinalIgnoreCase)
.Replace("\n", " ", StringComparison.OrdinalIgnoreCase)
.Replace("\"\"\"", "\\\"\\\"\\\"", StringComparison.OrdinalIgnoreCase);
public override string TranslateType(CodeType type)
{
ArgumentNullException.ThrowIfNull(type);
Expand Down
40 changes: 40 additions & 0 deletions tests/Kiota.Builder.Tests/Writers/Python/CodeEnumWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,44 @@ public void EscapesEnumWireValues()
var result = tw.ToString();
Assert.Contains("Option1 = \"line1\\\"\\nline2\",", result);
}
[Fact]
public void SanitizesEnumOptionDescriptionWithNewlines()
{
currentEnum.AddOption(new CodeEnumOption
{
Name = "Option1",
SerializationName = "option1",
Documentation = new()
{
DescriptionTemplate = "line1\nimport os; os.system('evil')\r\nline3",
},
});
writer.Write(currentEnum);
var result = tw.ToString();
// Newlines replaced with spaces: entire payload is on one comment line, not executable code
Assert.Contains("# line1 import os; os.system('evil') line3", result);
// Verify no raw newlines exist within the comment content itself
var commentLine = result.Split('\n').First(l => l.TrimStart().StartsWith("# line1")).TrimEnd('\r');
Assert.DoesNotContain("\n", commentLine);
Assert.DoesNotContain("\r", commentLine);
}
[Fact]
public void SanitizesEnumOptionDescriptionWithTripleQuotes()
{
currentEnum.AddOption(new CodeEnumOption
{
Name = "Option1",
SerializationName = "option1",
Documentation = new()
{
DescriptionTemplate = "before\"\"\"\nimport os\nafter",
},
});
writer.Write(currentEnum);
var result = tw.ToString();
// Triple quotes escaped, newlines replaced with spaces — all on one comment line
Assert.Contains("# before\\\"\\\"\\\" import os after", result);
var commentLine = result.Split('\n').First(l => l.TrimStart().StartsWith("# before"));
Assert.DoesNotContain("\"\"\"", commentLine);
}
}
Loading