[master] questions about recent changes in xlat

Chaigneau, Nicolas nicolas.chaigneau at capgemini.com
Sun Oct 25 19:59:57 CET 2020

> > Alright, I found out why it does not work.
> > 
> > In function _xlat_eval:
> > 
> > 	len = xlat_tokenize_ephemeral(ctx, &node, NULL,
> > 				      &FR_SBUFF_IN(fmt, strlen(fmt)),
> > 				      NULL, &(tmpl_rules_t){ .dict_def = request->dict });
> > 
> > 
> > _xlat_eval does not provide a "fr_sbuff_parse_rules_t" with the escape function.
> > As compared with the code in unit tests, which does:
> > 
> > 			fr_sbuff_parse_rules_t	p_rules = { .escapes = &fr_value_unescape_double };
> > 
> > 			slen = xlat_tokenize_ephemeral(xlat_ctx, &head, NULL,
> > 						       &FR_SBUFF_IN(fmt, talloc_array_length(fmt) - 1), &p_rules, NULL);
>   Changing that doesn't make any difference in my tests.
>   I've added a test to src/tests/keywords/xlat-escape.  It does what I expect it to do.
>   So... what's the use-case for your tests?  How can I reproduce them here?

My use case is the following:

I receive a string buffer from an external source, which can contain any text (encoding doesn't matter).
Xlat expressions are allowed in this buffer.
This entails that if the text contains some random "%" characters which would trigger expansion, they must be escaped.

For example: "this must be xlated: %D, these however must not be modified: \%{  \%D  \x61 \t".

Previously I just needed to double the "%" ("%%") to make it work.
Now as I understand, I have to change the escaping (in the received text) as follows: "\%".

This does not work with "xlat_eval" function, because it does not provide an unescape function to xlat_tokenize_ephemeral  (through parameter "fr_sbuff_parse_rules_t const *p_rules")

So I need to call xlat_tokenize_ephemeral with my own sbuff unescape rules, that I defined as follow:

fr_sbuff_unescape_rules_t fr_value_unescape_xlat = {
	.name = "xlat",
	.chr = '\\',
	.subs = {
		['%'] = '%',	/* xlat expansions */
	.do_hex = false,
	.do_oct = false

(I can't use fr_value_unescape_double because this would do things I don't want, e.g. "\x61" would be modified to "a").

The following code shows how to reproduce my issue (the two "p_rules" commented out do not provide the result that  I want, the uncommented "p_rules" does).

	char *fmt = "this must be xlated: %D, these however must not be modified: \\%{  \\%D  \\x61 \\t";
	ssize_t slen;
	TALLOC_CTX *xlat_ctx = talloc_init_const("xlat");
	xlat_exp_t *head = NULL;
	//fr_sbuff_parse_rules_t p_rules = { }; // nope
	//fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double }; // nope
	fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_xlat };

	slen = xlat_tokenize_ephemeral(xlat_ctx, &head, NULL,
				       &FR_SBUFF_IN(fmt, strlen(fmt)), &p_rules, NULL);

	slen = xlat_eval_compiled(out, outlen, request, head, NULL, NULL);

This message contains information that may be privileged or confidential and is the property of the Capgemini Group. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorized to read, print, retain, copy, disseminate, distribute, or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message.

More information about the Freeradius-Devel mailing list