ฉันได้รับมัน. และใช่มันเป็นจุดบกพร่อง
ปัญหาคือมีสองระดับที่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 ())) `หรือไม่