mirror of https://github.com/Squidex/squidex.git
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
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();
|
|
}
|
|
}
|
|
|