Skip to content

Commit a7a9f5f

Browse files
JSON to be delivered in HTML must not escape ampersand (#812)
* JSON to be delivered in HTML must not escape ampersand, it is escaped later in HtmlEncodeInputValue. * Do not delimit encoded json at HtmlEncodeJsonValue. It is already delimited outside HtmlEncodeJsonValue use. (cherry picked from commit ba9c5eb)
1 parent 2cc5a58 commit a7a9f5f

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

dotnet/src/dotnetframework/GxClasses/Helpers/HttpHelper.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using System.Runtime.Serialization;
2626
using GeneXus.Mime;
2727
using System.Text.RegularExpressions;
28+
using System.Globalization;
2829

2930
namespace GeneXus.Http
3031
{
@@ -349,6 +350,82 @@ public static string[] GetParameterValues(string query)
349350
return query.Split(',');
350351
}
351352
}
353+
internal static string HtmlEncodeJsonValue(string value)
354+
{
355+
return GXUtil.HtmlEncodeInputValue(JsonQuote(value));
356+
}
357+
358+
static void AppendCharAsUnicodeJavaScript(StringBuilder builder, char c)
359+
{
360+
builder.Append("\\u");
361+
int num = c;
362+
builder.Append(num.ToString("x4", CultureInfo.InvariantCulture));
363+
}
364+
/**
365+
* Produce a string in double quotes with backslash sequences in all the
366+
* right places. A backslash will be inserted within </, allowing JSON
367+
* text to be delivered in HTML. In JSON text, a string cannot contain a
368+
* control character or an unescaped quote or backslash.
369+
* */
370+
internal static string JsonQuote(string value, bool addDoubleQuotes=false)
371+
{
372+
string text = string.Empty;
373+
if (!string.IsNullOrEmpty(value))
374+
{
375+
int i;
376+
int len = value.Length;
377+
StringBuilder sb = new StringBuilder(len + 4);
378+
379+
for (i = 0; i < len; i += 1)
380+
{
381+
char c = value[i];
382+
switch (c)
383+
{
384+
case '\\':
385+
case '"':
386+
sb.Append('\\');
387+
sb.Append(c);
388+
break;
389+
case '\b':
390+
sb.Append("\\b");
391+
break;
392+
case '\t':
393+
sb.Append("\\t");
394+
break;
395+
case '\n':
396+
sb.Append("\\n");
397+
break;
398+
case '\f':
399+
sb.Append("\\f");
400+
break;
401+
case '\r':
402+
sb.Append("\\r");
403+
break;
404+
default:
405+
{
406+
if (c < ' ')
407+
{
408+
AppendCharAsUnicodeJavaScript(sb, c);
409+
}
410+
else
411+
{
412+
sb.Append(c);
413+
}
414+
}
415+
break;
416+
}
417+
}
418+
text = sb.ToString();
419+
}
420+
if (!addDoubleQuotes)
421+
{
422+
return text;
423+
}
424+
else
425+
{
426+
return "\"" + text + "\"";
427+
}
428+
}
352429

353430
}
354431
#if NETCORE

dotnet/src/dotnetframework/GxClasses/Middleware/GXHttp.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1548,7 +1548,7 @@ protected void SendState()
15481548
context.httpAjaxContext.AddStylesHidden();
15491549
if (IsSpaRequest())
15501550
{
1551-
context.WriteHtmlTextNl("<script>gx.ajax.saveJsonResponse('" + GXUtil.HtmlEncodeInputValue(HttpUtility.JavaScriptStringEncode(context.getJSONResponse())) + "');</script>");
1551+
context.WriteHtmlTextNl("<script>gx.ajax.saveJsonResponse('" + HttpHelper.HtmlEncodeJsonValue(context.getJSONResponse()) + "');</script>");
15521552
}
15531553
else
15541554
{

0 commit comments

Comments
 (0)