Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

71 lines
2.5 KiB

// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Globalization;
using System.Text;
using Squidex.Infrastructure.Queries;
namespace Squidex.Providers.SqlServer;
internal static class Extensions
{
public static StringBuilder AppendJsonPath(this StringBuilder sb, PropertyPath path)
{
sb.Append('[');
// Escape embedded closing brackets so a crafted path segment cannot break out of the identifier.
sb.Append(path[0].Replace("]", "]]", StringComparison.Ordinal));
sb.Append("], ");
sb.AppendJsonSubPath(path);
return sb;
}
public static StringBuilder AppendJsonSubPath(this StringBuilder sb, PropertyPath path)
{
sb.Append("\'$");
foreach (var property in path.Skip(1))
{
if (int.TryParse(property, NumberStyles.Integer, CultureInfo.InvariantCulture, out var index))
{
sb.Append(CultureInfo.InvariantCulture, $"[{index}]");
}
else
{
sb.Append('.');
sb.Append('"');
sb.Append(EscapeProperty(property));
sb.Append('"');
}
}
sb.Append('\'');
return sb;
}
// The property name is a user-controlled JSON path segment that is embedded as a double-quoted
// member inside a single-quoted SQL string literal. Escape backslashes and double-quotes at the
// JSON-path level and single-quotes at the SQL-literal level to prevent SQL injection. SQL Server
// does not treat the backslash as a string-literal escape character, so the JSON-path escapes
// reach the JSON parser verbatim.
private static string EscapeProperty(string property)
{
return property
.Replace("\\", "\\\\", StringComparison.Ordinal)
.Replace("\"", "\\\"", StringComparison.Ordinal)
.Replace("'", "''", StringComparison.Ordinal);
}
public static string JsonSubPath(this PropertyPath path)
{
return new StringBuilder().AppendJsonSubPath(path).ToString();
}
public static string JsonPath(this PropertyPath path)
{
return new StringBuilder().AppendJsonPath(path).ToString();
}
}