删除用户输入字段中过多的空格
本文关键字:空格 用户 输入 字段 删除 | 更新日期: 2023-09-27 18:31:05
在我的控制器方法中,用于处理(潜在的敌对)用户输入字段,我有以下代码:
string tmptext = comment.Replace(System.Environment.NewLine, "{break was here}"); //marks line breaks for later re-insertion
tmptext = Encoder.HtmlEncode(tmptext);
//other sanitizing goes in here
tmptext = tmptext.Replace("{break was here}", "<br />");
var regex = new Regex("(<br /><br />)''1+");
tmptext = regex.Replace(tmptext, "$1");
我的目标是为典型的非恶意使用保留换行符,并以安全的 html 编码字符串显示用户输入。 我接受用户输入,解析换行符并在换行符处放置分隔符。我执行 HTML 编码并重新插入中断。(我可能会将其更改为将段落重新插入为 p 标签而不是 br,但现在我使用的是 br)
现在实际上插入真正的 html 中断打开了一个微妙的漏洞:Enter 键。regex.replace 代码用于去除恶意用户,只需站在 Enter 键上并用垃圾填充页面。
这是对只有白色的大垃圾洪水的修复,但仍然让我容易受到滥用,例如在页面上输入一个字符、两个换行符、一个字符、两个换行符。
我的问题是确定这是滥用并在验证时失败的方法。我担心可能没有一个简单的程序方法来做到这一点,而是需要启发式技术或贝叶斯滤波器。希望有人有一个更简单,更好的方法。
编辑:也许我在问题描述中不清楚,正则表达式处理连续查看多个换行符并将它们转换为一两个。 这个问题解决了。真正的问题是将合法文本与垃圾洪水区分开来:
一个
一个
一个
。想象一下其中的 1000 个...
一个
一个
一个
一个
随机建议,灵感来自slashdot.org的评论过滤器:使用System.IO.Compression.DeflateStream压缩你的用户输入,如果它与原始输入相比太小(你必须做一些实验才能找到一个有用的截止点),拒绝它。
我会HttpUtility.HtmlEncode
字符串,然后将换行符转换为<br/>
.
HttpUtility.HtmlEncode(subject).Replace("'r'n", "<br/>").Replace("'r", "<br/>").Replace("'n", "<br/>");
此外,您应该在输出给用户时执行此逻辑,而不是在数据库中保存时。 我对数据库进行的唯一验证是确保它已正确转义(除了正常的业务规则)。
编辑:但是,要解决实际问题,您可以使用正则表达式事先用单个换行符替换多个换行符。
subject = Regex.Replace(@"('r'n|'r|'n)+", @"'n", RegexOptions.Singleline);
我不确定你是否需要RegexOptions.Singleline
.
听起来你很想用正则表达式尝试一些"聪明"的东西,但 IMO 最简单的方法是循环访问字符串的字符,将它们复制到 StringBuilder,边走边过滤。
任何失败的字符。IsWhiteSpace() 测试不会被复制。(如果其中一个是换行符,则插入
,并且在点击非空格字符之前不允许再添加任何
)。
编辑
如果你想阻止用户输入任何旧的废话,现在就放弃。你永远不会找到一种过滤方式,如果用户真的想的话,他们无法在不到一分钟的时间内找到解决方法。
最好限制输入中的换行符数或字符总数。
想想做一些聪明的事情来净化"不良输入"需要付出多少努力,然后考虑这种情况发生的可能性有多大。可能没有意义。可能您真正需要的所有清理都是为了确保数据是合法的(对于您的系统来说不会太大而无法处理,所有危险字符都被剥离或逃脱等)。(这正是论坛有人工版主的原因,他们可以根据任何适当的标准过滤帖子)。
这不是最有效的处理方式,也不是最聪明的方法(免责声明),
但是,如果你的文本不是太大,那就无关紧要了,也没有任何更聪明的算法(注意:很难检测到类似char'nchar'nchar'n...
的东西,尽管你可以在 len 上设置一个限制)
你可以只Split
白色字符(添加你能想到的任何字符,除了 ') - 然后只用一个空格Join
,然后在<br />
上拆分(以获得行) - 用line.Length > 2
连接。在连接线路时,您可以测试DistinctUntilChanged
例如或其他东西。
为了加快速度,您可以使用更有效的算法进行迭代,逐个字符,使用 IndexOf 等。
同样不是处理这个问题的最有效或最完美的方法,但会给你一些快速的东西。
编辑:过滤"相同的行" - 您可以使用例如 Ix - Interactive extensions
- 这是来自<br />
(我认为请参阅 NuGet Ix-实验),它应该连续过滤"相同行"+ 您可以为它们添加行测试。
与其尝试用过滤文本替换换行符,然后尝试使用正则表达式,为什么不在插入HttpUtility.HtmlEncode
标签之前清理您的数据?不要忘记先用CC_14清理输入。
为了连续处理多条短线,这是我最好的尝试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Program {
static void Main() {
// Arbirary cutoff used to join short strings.
const int Cutoff = 6;
string input =
"'r'n'r'n'n'r'r'r'n'nthisisatest'r'nstring'r'nwith'nsome'r'n" +
"unsanatized'r'nbreaks'r'nand'ra'nsh'nor'nt'r'n'na'na'na'na" +
"'na'na'na'na'na'na'na'na'na'na'na'na'na'na'na'na'na";
input = (input ?? String.Empty).Trim(); // Don't forget to HtmlEncode it.
StringBuilder temp = new StringBuilder();
List<string> result = new List<string>();
var items = input.Split(
new[] { ''r', ''n' },
StringSplitOptions.RemoveEmptyEntries)
.Select(i => new { i.Length, Value = i });
foreach (var item in items) {
if (item.Length > Cutoff) {
if (temp.Length > 0) {
result.Add(temp.ToString());
temp.Clear();
}
result.Add(item.Value);
continue;
}
if (temp.Length > 0) { temp.Append(" "); }
temp.Append(item.Value);
}
if (temp.Length > 0) {
result.Add(temp.ToString());
}
Console.WriteLine(String.Join("<br />", result));
}
}
生成以下输出:
thisisatest<br />string with some<br />unsanatized<br />breaks and a sh or t a a
a a a a a a a a a a a a a a a a a a a
我相信你已经想出了这个解决方案,但不幸的是,你所要求的不是很简单。
对于那些感兴趣的人,这是我的第一次尝试:
using System;
using System.Text.RegularExpressions;
class Program {
static void Main() {
string input = "'r'n'r'n'n'r'r'r'n'nthisisatest'r'nstring'r'nwith'nsome" +
"'r'nunsanatized'r'nbreaks'r'n'r'n";
input = (input ?? String.Empty).Trim().Replace("'r", String.Empty);
string output = Regex.Replace(
input,
"'''n+",
"<br />",
RegexOptions.Multiline);
Console.WriteLine(output);
}
}
生成以下输出:
thisisatest<br />string<br />with<br />some<br />unsanatized<br />breaks