无效的字符串格式¶
ID: cs/invalid-string-formatting
Kind: path-problem
Security severity:
Severity: error
Precision: high
Tags:
- reliability
- maintainability
Query suites:
- csharp-security-and-quality.qls
使用字符串格式化方法(例如 string.Format()
)时,应考虑以下因素
格式字符串必须格式正确,否则将引发异常
System.FormatException
。格式字符串应使用所有传递的参数,否则将忽略此类参数。
缺少参数将导致引发
System.FormatException
异常。
建议¶
更改格式字符串,使其格式正确。确保每个格式项都符合语法
{index[,alignment][:formatString]}
{
或}
,请分别将它们替换为{{
和}}
,或将它们作为参数提供。更改格式字符串以使用突出显示的参数,或删除不必要的参数。
向格式化方法提供正确数量的参数,或更改格式字符串以使用正确的参数。
示例¶
在此示例中,格式字符串同时使用了字面量 {
和 }
,但这些字面量未正确转义。
using System;
class Bad1
{
string GenerateEmptyClass(string c)
{
return string.Format("class {0} { }", "C");
}
}
在修改后的示例中,字面量已正确转义。
using System;
class Good1
{
string GenerateEmptyClass(string c)
{
return string.Format("class {0} {{ }}", "C");
}
}
示例¶
以下是格式字符串未使用所有参数的三个示例。
using System;
class Bad2
{
void M(Exception ex)
{
Console.WriteLine("Error processing file: {0}", ex, ex.HResult);
Console.WriteLine("Error processing file: {1} ({1})", ex, ex.HResult);
Console.WriteLine("Error processing file: %s (%d)", ex, ex.HResult);
}
}
在第 7 行,未记录第二个参数 (
ex.HResult
)。在第 8 行,未记录第一个参数 (
ex
),但记录了两次第二个参数 (ex.HResult
)。在第 9 行,使用了 C 样式的格式字符串,这是不正确的,并且不会记录任何参数。
示例¶
以下是调用 String.Format()
缺少参数的两个示例。
using System;
class Bad3
{
void Hello(string first, string last)
{
Console.WriteLine("Hello {0} {1}", first);
Console.WriteLine("Hello {1} {2}", first, last);
}
}
在第 7 行,未提供第二个参数 (
last
)。在第 8 行,格式项的编号为
{1}
和{2}
,而它们应该是{0}
和{1}
。在修改后的示例中,提供了两个参数。
using System;
class Good3
{
void Hello(string first, string last)
{
Console.WriteLine("Hello {0} {1}", first, last);
}
}
参考¶
MSDN:String.Format 方法。
Microsoft:复合格式字符串。