Skip to content

Commit d037843

Browse files
committed
feat: nested macro expansion
1 parent 50620aa commit d037843

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

apache2/re_actions.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,56 @@ int expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t
201201
text_start = next_text_start;
202202
p = strstr(text_start, "%");
203203
if (p != NULL) {
204+
// check for embedded macros
205+
char *embedded_macro = strstr(p + 1, "%");
206+
if (embedded_macro != NULL) {
207+
if ((*(embedded_macro + 1) == '{')&&(*(embedded_macro + 2) != '\0')) {
208+
char *var_start = embedded_macro;
209+
210+
char * et = var_start;
211+
// Find the end of the embedded macro.
212+
while((*et != '\0')&&(*et != '}')) et++;
213+
if (*et == '}') {
214+
// Found embedded macro, resolve it and replace in the string.
215+
char *embedded_macro_name = apr_pstrmemdup(mptmp, var_start, et - var_start + 1);
216+
msr_log(msr, 9, "Expand macros: found embedded var: \"%s\"",
217+
log_escape_ex(mptmp, embedded_macro_name, et - var_start + 1)
218+
);
219+
msc_string * embedded_var = (msc_string *)apr_pcalloc(mptmp, sizeof(msc_string));
220+
embedded_var->value = apr_pstrdup(mptmp, embedded_macro_name);
221+
embedded_var->value_len = strlen(embedded_var->value);
222+
expand_macros(msr, embedded_var, rule, mptmp);
223+
msr_log(msr, 9, "Expand macros: resolved embedded var \"%s\" to \"%s\"",
224+
log_escape_ex(mptmp, embedded_macro_name, et - var_start + 1),
225+
log_escape_ex(mptmp, embedded_var->value, embedded_var->value_len)
226+
);
227+
// Replace the embedded macro in data with the resolved value.
228+
char * new_data = apr_pstrcat(mptmp,
229+
apr_pstrndup(mptmp, data, var_start - data),
230+
embedded_var->value,
231+
apr_pstrdup(mptmp, et + 1),
232+
NULL
233+
);
234+
size_t embedded_offset = text_start - data;
235+
size_t old_p_offset = p - data;
236+
data = new_data;
237+
text_start = data + embedded_offset;
238+
var->value = data;
239+
var->value_len = strlen(var->value);
240+
p = data + old_p_offset;
241+
}
242+
else {
243+
msr_log(msr, 1, "Expand macros: embedded macro appears to be unterminated: \"%s\"",
244+
log_escape_ex(mptmp, embedded_macro, strlen(embedded_macro))
245+
);
246+
}
247+
}
248+
else {
249+
msr_log(msr, 1, "Expand macros: found embedded '%%' but it does not appear to be a valid macro: \"%s\"",
250+
log_escape_ex(mptmp, embedded_macro, strlen(embedded_macro))
251+
);
252+
}
253+
}
204254
char *var_name = NULL;
205255
char *var_value = NULL;
206256

0 commit comments

Comments
 (0)