Skip to content

Commit

Permalink
EscapeHtml PoC
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlosFigueiraMSFT committed Feb 3, 2024
1 parent 913a85e commit 685aa72
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/libraries/Microsoft.PowerFx.Core/Localization/Strings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ internal static class TexlStrings
public static StringGetter AboutEncodeUrl = (b) => StringResources.Get("AboutEncodeUrl", b);
public static StringGetter EncodeUrlArg1 = (b) => StringResources.Get("EncodeUrlArg1", b);

public static StringGetter AboutEscapeHtml = (b) => StringResources.Get("AboutEscapeHtml", b);
public static StringGetter EscapeHtmlArg1 = (b) => StringResources.Get("EscapeHtmlArg1", b);

public static StringGetter AboutPlainText = (b) => StringResources.Get("AboutPlainText", b);
public static StringGetter PlainTextArg1 = (b) => StringResources.Get("PlainTextArg1", b);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ internal class BuiltinFunctionsCore
public static readonly TexlFunction EncodeUrl = _library.Add(new EncodeUrlFunction());
public static readonly TexlFunction EndsWith = _library.Add(new EndsWithFunction());
public static readonly TexlFunction Error = _library.Add(new ErrorFunction());
public static readonly TexlFunction EscapeHtml = _library.Add(new EscapeHtmlFunction());
public static readonly TexlFunction Exp = _library.Add(new ExpFunction());
public static readonly TexlFunction ExpT = _library.Add(new ExpTableFunction());
public static readonly TexlFunction Filter = _library.Add(new FilterFunction());
Expand Down
23 changes: 23 additions & 0 deletions src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/EscapeHtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using System.Collections.Generic;
using Microsoft.PowerFx.Core.Localization;
using Microsoft.PowerFx.Core.Texl.Builtins;
using Microsoft.PowerFx.Core.Types;

namespace Microsoft.PowerFx.Core.Texl
{
internal sealed class EscapeHtmlFunction : StringOneArgFunction
{
public EscapeHtmlFunction()
: base("EscapeHtml", TexlStrings.AboutEscapeHtml, FunctionCategories.Text)
{
}

public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()
{
yield return new[] { TexlStrings.EscapeHtmlArg1 };
}
}
}
11 changes: 11 additions & 0 deletions src/libraries/Microsoft.PowerFx.Interpreter/Functions/Library.cs
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,17 @@ static Library()
returnBehavior: ReturnBehavior.ReturnFalseIfAnyArgIsBlank,
targetFunction: Error)
},
{
BuiltinFunctionsCore.EscapeHtml,
StandardErrorHandling<StringValue>(
BuiltinFunctionsCore.EncodeUrl.Name,
expandArguments: NoArgExpansion,
replaceBlankValues: NoOpAlreadyHandledByIR,
checkRuntimeTypes: ExactValueType<StringValue>,
checkRuntimeValues: DeferRuntimeValueChecking,
returnBehavior: ReturnBehavior.AlwaysEvaluateAndReturnResult,
targetFunction: EscapeHtml)
},
{
BuiltinFunctionsCore.Exp,
StandardErrorHandling<NumberValue>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Microsoft.PowerFx.Core.IR;
using Microsoft.PowerFx.Core.Localization;
using Microsoft.PowerFx.Core.Utils;
Expand Down Expand Up @@ -801,6 +802,12 @@ public static FormulaValue EncodeUrl(IRContext irContext, StringValue[] args)
return new StringValue(irContext, Uri.EscapeDataString(args[0].Value));
}

public static FormulaValue EscapeHtml(IRContext irContext, StringValue[] args)
{
var encoded = HttpUtility.HtmlEncode(args[0].Value);
return new StringValue(irContext, encoded);
}

public static FormulaValue Proper(EvalVisitor runner, EvalVisitorContext context, IRContext irContext, StringValue[] args)
{
return new StringValue(irContext, runner.CultureInfo.TextInfo.ToTitleCase(runner.CultureInfo.TextInfo.ToLower(args[0].Value)));
Expand Down
11 changes: 11 additions & 0 deletions src/strings/PowerFxResources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -4092,6 +4092,17 @@
<data name="AboutEncodeUrl_url" xml:space="preserve">
<value>A url to be encoded.</value>
</data>
<data name="AboutEscapeHtml" xml:space="preserve">
<value>Converts a text to an HTML-encoded text.</value>
<comment>Description of 'EncodeUrl' function.</comment>
</data>
<data name="EscapeHtmlArg1" xml:space="preserve">
<value>value</value>
<comment>Function_parameter - First parameter for the EscapeHtml function - the value (string) to escape.</comment>
</data>
<data name="AboutEscapeHtml_value" xml:space="preserve">
<value>A text to be escaped.</value>
</data>
<data name="ErrUnimplementedFunction" xml:space="preserve">
<value>'{0}' is a recognized but not supported function.</value>
<comment>Error Message.</comment>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Escaping
>> EscapeHtml("<p>A paragraph</p>")
"&lt;p&gt;A paragraph&lt;/p&gt;"

// Multiple encodings
>> EscapeHtml("<h1>Mac & cheese</h1>")
"&lt;h1&gt;Mac &amp; cheese&lt;/h1&gt;"

// Quotes
>> EscapeHtml("A value with ""double"" and 'single' quotes")
"A value with &quot;double&quot; and &#39;single&#39; quotes"

// \u00A0 to \u00af - escaped
>> EscapeHtml(Concat(Sequence(16, 160), UniChar(Value)))
"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;"

// \u0090 to \u009f - not escaped
>> With({str:Concat(Sequence(16, 144), UniChar(Value))}, str = EscapeHtml(str))
true

// \u00A0 to \u00ff - escaped
>> With({str:EscapeHtml(Concat(Sequence(96, 160), UniChar(Value))), expectedEscaped:Concat(Sequence(96, 160), $"&#{Value};")}, str = expectedEscaped)
true

// \u0100... not escaped
>> EscapeHtml("<b>ĀāĂă</b>")
"&lt;b&gt;ĀāĂă&lt;/b&gt;"

// Blanks
>> EscapeHtml(Blank())
""

// Errors
>> EscapeHtml(Char(-1))
Error({Kind:ErrorKind.InvalidArgument})

// Escaping surrogate pairs
>> EscapeHtml("<ul><li>not a pair: ❤</li><li>a surrogate pair: 💩</li></ul>")
"&lt;ul&gt;&lt;li&gt;not a pair: ❤&lt;/li&gt;&lt;li&gt;a surrogate pair: &#128169;&lt;/li&gt;&lt;/ul&gt;"

>> EscapeHtml("Osage alphabet (start): 𐒰𐒱𐒲𐒳𐒴𐒵𐒶")
"Osage alphabet (start): &#66736;&#66737;&#66738;&#66739;&#66740;&#66741;&#66742;"
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"EndsWith",
"EOMonth",
"Error",
"EscapeHtml",
"Exp",
"Filter",
"Find",
Expand Down

0 comments on commit 685aa72

Please sign in to comment.