fast_json/Tests/TestJsonHardening.mq5

87 lines
2.9 KiB
MQL5
Raw Permalink Normal View History

//+------------------------------------------------------------------+
//| TestJsonHardening.mq5 |
//| AI-Toolkit |
//+------------------------------------------------------------------+
#property script_show_inputs
#include "../fast_json.mqh"
void OnStart() {
Print("=== JSON HARDENING & ROBUSTNESS TEST ===");
//---------------------------------------------------------
// 1. PRETTY PRINT
//---------------------------------------------------------
Print("\n--- 1. Pretty Print Test ---");
string raw = "{\"a\":1,\"b\":[true,false,null,{\"x\":99.9}]}";
CJson pp_doc;
if (pp_doc.Parse(raw)) {
string pretty = pp_doc.Serialize(true); // true = pretty
Print("Pretty Output:\n", pretty);
// Check for newlines
if (StringFind(pretty, "\n") >= 0 && StringFind(pretty, " ") >= 0)
Print("PASS: Pretty Print indentation detected.");
else
Print("FAIL: Pretty Print failed.");
}
//---------------------------------------------------------
// 2. ERROR CONTEXT (Line/Col)
//---------------------------------------------------------
Print("\n--- 2. Error Context (Line/Col) ---");
string bad_json = "{\n \"valid\": 1,\n \"broken\": UNQUOTED_VALUE\n}";
CJson bad_doc;
if (!bad_doc.Parse(bad_json)) {
int line, col;
bad_doc.GetErrorPos(line, col);
Print("Error Code: ", EnumToString((EnumJsonError)bad_doc.GetLastError()));
Print("Location: Line ", line, ", Col ", col);
// "broken": starts at line 3. Value starts after.
// 1: {
// 2: "valid": 1,
// 3: "broken": UNQUOTED_VALUE
// The error should be around Line 3, Col ~13
if (line == 3 && col > 10)
Print("PASS: Error location accurate.");
else
Print("FAIL: Error location mismatch. Expected Line 3.");
} else {
Print("FAIL: Should have failed parsing!");
}
//---------------------------------------------------------
// 3. STACK OVERFLOW ATTACK
//---------------------------------------------------------
Print("\n--- 3. Stack Exhaustion Attack ---");
CJsonBuilder bomb_b(65536);
// Create depth > 512
int depth = 600;
string deep = "";
for (int i = 0; i < depth; i++)
deep += "[";
// We manually construct string because Builder might check sp too (which is
// good) But we want to test PARSER safety.
Print("Parsing Depth: ", depth);
CJson bomb_doc;
// This should return false, NOT CRASH
// If it crashes, this script stops dead.
bool res = bomb_doc.Parse(deep);
if (!res) {
int err = bomb_doc.GetLastError();
Print("Parse Result: Error ", EnumToString((EnumJsonError)err));
if (err == JSON_ERR_STACK_OVERFLOW)
Print("PASS: Stack Overflow caught gracefully.");
else
Print("FAIL: Wrong error code.");
} else {
Print("FAIL: Should have failed deep recursion!");
}
Print("\n=== SUITE COMPLETE ===");
}