|
1 | 1 | /* |
2 | 2 | * ModSecurity, http://www.modsecurity.org/ |
3 | | - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) |
| 3 | + * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/) |
4 | 4 | * |
5 | 5 | * You may not use this file except in compliance with |
6 | 6 | * the License. You may obtain a copy of the License at |
@@ -39,97 +39,88 @@ bool ValidateSchema::init(const std::string &file, std::string *error) { |
39 | 39 | } |
40 | 40 |
|
41 | 41 |
|
42 | | -bool ValidateSchema::evaluate(Transaction *t, |
| 42 | +bool ValidateSchema::evaluate(Transaction *transaction, |
43 | 43 | const std::string &str) { |
44 | | - int rc; |
45 | 44 |
|
46 | | - m_parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str()); |
47 | | - if (m_parserCtx == NULL) { |
| 45 | + if (transaction->m_xml->m_data.doc == NULL) { |
| 46 | + ms_dbg_a(transaction, 4, "XML document tree could not be found for " \ |
| 47 | + "schema validation."); |
| 48 | + return true; |
| 49 | + } |
| 50 | + |
| 51 | + if (transaction->m_xml->m_data.well_formed != 1) { |
| 52 | + ms_dbg_a(transaction, 4, "XML: Schema validation failed because " \ |
| 53 | + "content is not well formed."); |
| 54 | + return true; |
| 55 | + } |
| 56 | + |
| 57 | + xmlSchemaParserCtxtPtr parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str()); |
| 58 | + if (parserCtx == NULL) { |
48 | 59 | std::stringstream err; |
49 | 60 | err << "XML: Failed to load Schema from file: "; |
50 | 61 | err << m_resource; |
51 | 62 | err << ". "; |
52 | 63 | if (m_err.empty() == false) { |
53 | 64 | err << m_err; |
54 | 65 | } |
55 | | - ms_dbg_a(t, 4, err.str()); |
| 66 | + ms_dbg_a(transaction, 4, err.str()); |
56 | 67 | return true; |
57 | 68 | } |
58 | 69 |
|
59 | | - xmlSchemaSetParserErrors(m_parserCtx, |
| 70 | + xmlSchemaSetParserErrors(parserCtx, |
60 | 71 | (xmlSchemaValidityErrorFunc)error_load, |
61 | 72 | (xmlSchemaValidityWarningFunc)warn_load, &m_err); |
62 | 73 |
|
63 | | - xmlThrDefSetGenericErrorFunc(m_parserCtx, |
| 74 | + xmlThrDefSetGenericErrorFunc(parserCtx, |
64 | 75 | null_error); |
65 | 76 |
|
66 | | - xmlSetGenericErrorFunc(m_parserCtx, |
| 77 | + xmlSetGenericErrorFunc(parserCtx, |
67 | 78 | null_error); |
68 | 79 |
|
69 | | - m_schema = xmlSchemaParse(m_parserCtx); |
70 | | - if (m_schema == NULL) { |
| 80 | + xmlSchemaPtr schema = xmlSchemaParse(parserCtx); |
| 81 | + if (schema == NULL) { |
71 | 82 | std::stringstream err; |
72 | 83 | err << "XML: Failed to load Schema: "; |
73 | 84 | err << m_resource; |
74 | 85 | err << "."; |
75 | 86 | if (m_err.empty() == false) { |
76 | 87 | err << " " << m_err; |
77 | 88 | } |
78 | | - ms_dbg_a(t, 4, err.str()); |
79 | | - xmlSchemaFreeParserCtxt(m_parserCtx); |
| 89 | + ms_dbg_a(transaction, 4, err.str()); |
| 90 | + xmlSchemaFreeParserCtxt(parserCtx); |
80 | 91 | return true; |
81 | 92 | } |
82 | 93 |
|
83 | | - m_validCtx = xmlSchemaNewValidCtxt(m_schema); |
84 | | - if (m_validCtx == NULL) { |
| 94 | + xmlSchemaValidCtxtPtr validCtx = xmlSchemaNewValidCtxt(schema); |
| 95 | + if (validCtx == NULL) { |
85 | 96 | std::stringstream err("XML: Failed to create validation context."); |
86 | 97 | if (m_err.empty() == false) { |
87 | 98 | err << " " << m_err; |
88 | 99 | } |
89 | | - ms_dbg_a(t, 4, err.str()); |
| 100 | + ms_dbg_a(transaction, 4, err.str()); |
| 101 | + xmlSchemaFree(schema); |
| 102 | + xmlSchemaFreeParserCtxt(parserCtx); |
90 | 103 | return true; |
91 | 104 | } |
92 | 105 |
|
93 | 106 | /* Send validator errors/warnings to msr_log */ |
94 | | - xmlSchemaSetValidErrors(m_validCtx, |
| 107 | + xmlSchemaSetValidErrors(validCtx, |
95 | 108 | (xmlSchemaValidityErrorFunc)error_runtime, |
96 | | - (xmlSchemaValidityWarningFunc)warn_runtime, t); |
| 109 | + (xmlSchemaValidityWarningFunc)warn_runtime, transaction); |
97 | 110 |
|
98 | | - if (t->m_xml->m_data.doc == NULL) { |
99 | | - ms_dbg_a(t, 4, "XML document tree could not be found for " \ |
100 | | - "schema validation."); |
101 | | - return true; |
102 | | - } |
| 111 | + int rc = xmlSchemaValidateDoc(validCtx, transaction->m_xml->m_data.doc); |
103 | 112 |
|
104 | | - if (t->m_xml->m_data.well_formed != 1) { |
105 | | - ms_dbg_a(t, 4, "XML: Schema validation failed because " \ |
106 | | - "content is not well formed."); |
107 | | - return true; |
108 | | - } |
109 | | - |
110 | | - /* Make sure there were no other generic processing errors */ |
111 | | - /* |
112 | | - if (msr->msc_reqbody_error) { |
113 | | - ms_dbg_a(t, 4, "XML: Schema validation could not proceed due to previous" |
114 | | - " processing errors."); |
115 | | - return true; |
116 | | - } |
117 | | - */ |
118 | | - |
119 | | - rc = xmlSchemaValidateDoc(m_validCtx, t->m_xml->m_data.doc); |
| 113 | + xmlSchemaFreeValidCtxt(validCtx); |
| 114 | + xmlSchemaFree(schema); |
| 115 | + xmlSchemaFreeParserCtxt(parserCtx); |
120 | 116 | if (rc != 0) { |
121 | | - ms_dbg_a(t, 4, "XML: Schema validation failed."); |
122 | | - xmlSchemaFree(m_schema); |
123 | | - xmlSchemaFreeParserCtxt(m_parserCtx); |
| 117 | + ms_dbg_a(transaction, 4, "XML: Schema validation failed."); |
124 | 118 | return true; /* No match. */ |
| 119 | + } else { |
| 120 | + ms_dbg_a(transaction, 4, "XML: Successfully validated payload against " \ |
| 121 | + "Schema: " + m_resource); |
| 122 | + return false; |
125 | 123 | } |
126 | | - |
127 | | - ms_dbg_a(t, 4, "XML: Successfully validated payload against " \ |
128 | | - "Schema: " + m_resource); |
129 | | - xmlSchemaFree(m_schema); |
130 | | - xmlSchemaFreeParserCtxt(m_parserCtx); |
131 | | - |
132 | | - return false; |
133 | 124 | } |
134 | 125 |
|
135 | 126 | #endif |
|
0 commit comments