Я отримав його. І так, це помилка.
Проблема в тому, що тут відбувається два рівні string.Format
.
Перший рівень форматування що - щось на кшталт:
string template = string.Format("Expected: {0}; Actual: {1}; Message: {2}",
expected, actual, message);
Потім ми використовуємо string.Format
з параметрами, які ви вказали:
string finalMessage = string.Format(template, parameters);
(Очевидно, що там є культури, і якась санітарія ... але недостатньо.)
Це виглядає нормально - якщо очікувані та фактичні значення самі не закінчаться фігурними дужками після перетворення в рядок - що вони і роблять Size
. Наприклад, ваш перший розмір перетворюється на:
{Width=0, Height=0}
Отже, другий рівень форматування приблизно такий:
string.Format("Expected: {Width=0, Height=0}; Actual: {Width=1, Height=1 }; " +
"Message = Failed expected {0} actually is {1}", struct1, struct2);
... і ось що не вдається. Ой.
Дійсно, ми можемо це довести дуже легко, обдуривши форматування, використовуючи наші параметри для очікуваної та фактичної частин:
var x = "{0}";
var y = "{1}";
Assert.AreEqual<object>(x, y, "What a surprise!", "foo", "bar");
Результат:
Assert.AreEqual failed. Expected:<foo>. Actual:<bar>. What a surprise!
Явно зламаний, оскільки ми не очікували, як foo
і не було фактичної вартості bar
!
В основному це схоже на атаку ін'єкції SQL, але в досить менш страшному контексті string.Format
.
Як обхідний шлях ви можете використовувати те, string.Format
як пропонує StriplingWarrior. Це дозволяє уникнути другого рівня форматування, що виконується в результаті форматування з фактичними / очікуваними значеннями.
Assert.AreEqual(struct1, struct2, string.Format("Failed expected {0} actually is {1}
, struct1.ToString (), struct2.ToString ())) `?