*
* Example: "%{urlquote:http://example.org/}" == "http%3A%47%47example.org%47"
*/
-static ssize_t urlquote_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
- UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
- UNUSED REQUEST *request, char const *fmt)
+static xlat_action_t xlat_urlquote(TALLOC_CTX *ctx, fr_cursor_t *out,
+ REQUEST *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
+ fr_value_box_t **in)
{
- char const *p;
- char *out_p = *out;
- size_t freespace = outlen;
+ char const *p, *end;
+ char *buff, *buff_p;
+ size_t outlen = 0;
+ fr_value_box_t *vb;
- if (outlen <= 1) return 0;
+ /*
+ * Nothing to do if input is empty
+ */
+ if (!(*in)) {
+ return XLAT_ACTION_DONE;
+ }
- p = fmt;
- while (*p && (--freespace > 0)) {
+ /*
+ * Concatenate all input
+ */
+ if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) {
+ RPEDEBUG("Failed concatenating input");
+ return XLAT_ACTION_FAIL;
+ }
+
+ p = (*in)->vb_strvalue;
+ end = p + (*in)->vb_length;
+
+ /*
+ * Calculate size of output
+ */
+ while (p < end) {
+ if (isalnum(*p) ||
+ *p == '-' ||
+ *p == '_' ||
+ *p == '.' ||
+ *p == '~') {
+ outlen++;
+ } else {
+ outlen += 3;
+ }
+ p++;
+ }
+
+ buff = buff_p = talloc_array(NULL, char, outlen + 1);
+
+ /* Reset p to start position */
+ p = (*in)->vb_strvalue;
+
+ while (p < end) {
if (isalnum(*p)) {
- *out_p++ = *p++;
+ *buff_p++ = *p++;
continue;
}
case '_':
case '.':
case '~':
- *out_p++ = *p++;
+ *buff_p++ = *p++;
break;
default:
- if (freespace < 3)
- break;
-
/* MUST be upper case hex to be compliant */
- snprintf(out_p, 4, "%%%02X", (uint8_t) *p++); /* %XX */
+ snprintf(buff_p, 4, "%%%02X", (uint8_t) *p++); /* %XX */
- /* Already decremented */
- freespace -= 2;
- out_p += 3;
+ buff_p += 3;
}
}
- *out_p = '\0';
+ *buff_p = '\0';
- return outlen - freespace;
+ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
+ fr_value_box_bstrsteal(vb, vb, NULL, buff, false);
+
+ fr_cursor_append(out, vb);
+
+ return XLAT_ACTION_DONE;
}
/** URLdecode special characters
XLAT_REGISTER(regex);
#endif
- xlat_register(NULL, "urlquote", urlquote_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_register(NULL, "urlunquote", urlunquote_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_register(NULL, "tolower", tolower_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_register(NULL, "toupper", toupper_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_async_register(NULL, "md5", xlat_md5, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
xlat_async_register(NULL, "rand", xlat_rand, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
xlat_async_register(NULL, "randstr", xlat_randstr, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ xlat_async_register(NULL, "urlquote", xlat_urlquote, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
return 0;
}
#
update {
# Some encoders replace ~ with %7E RFC3986 Section 2.4 says this should not be done.
- request:Tmp-String-0 := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.~'
- request:Tmp-String-1 := '±§!@#$%^&*()+={[}]:;"\'|\<,>?/`'
- request:Tmp-String-2 := '™œ¥¤'
- request:Tmp-String-3 := '%C2%B1%C2%A7%21%40%23%24%25%5E%26%2A%28%29%2B%3D%7B%5B%7D%5D%3A%3B%22%27%7C%5C%3C%2C%3E%3F%2F%60'
+ &Tmp-String-0 := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.~'
+ &Tmp-String-2 := '±§!@#$%^&*()+={[}]:;"\'|\<,>?/`'
+ &Tmp-String-4 := '™œ¥¤'
+ &Tmp-String-6 := '%C2%B1%C2%A7%21%40%23%24%25%5E%26%2A%28%29%2B%3D%7B%5B%7D%5D%3A%3B%22%27%7C%5C%3C%2C%3E%3F%2F%60'
+ &Tmp-String-8 := '%E2%84%A2%C5%93%C2%A5%C2%A4'
+}
- request:Tmp-String-4 := '%E2%84%A2%C5%93%C2%A5%C2%A4'
+update {
+ &Tmp-String-1 := "%{urlquote:%{Tmp-String-0}}"
+ &Tmp-String-3 := "%{urlquote:%{Tmp-String-2}}"
+ &Tmp-String-5 := "%{urlquote:%{Tmp-String-4}}"
+ &Tmp-String-7 := "%{urlunquote:%{Tmp-String-6}}"
+ &Tmp-String-9 := "%{urlunquote:%{Tmp-String-8}}"
}
-if (<string>"%{urlquote:%{request:Tmp-String-0}}" != &Tmp-String-0) {
+if (&Tmp-String-1 != &Tmp-String-0) {
test_fail
}
-if (<string>"%{urlquote:%{request:Tmp-String-1}}" != &Tmp-String-3) {
+if (&Tmp-String-3 != &Tmp-String-6) {
test_fail
}
-if (<string>"%{urlquote:%{request:Tmp-String-2}}" != &Tmp-String-4) {
+if (&Tmp-String-5 != &Tmp-String-8) {
test_fail
}
-if (<string>"%{urlunquote:%{request:Tmp-String-0}}" != &Tmp-String-0) {
+if (&Tmp-String-7 != &Tmp-String-2) {
test_fail
}
-if (<string>"%{urlunquote:%{request:Tmp-String-3}}" != &Tmp-String-1) {
+if (&Tmp-String-9 != &Tmp-String-4) {
+ test_fail
+}
+
+update request {
+ &Tmp-String-1 := "%{urlunquote:%{request:Tmp-String-0}}"
+ &Tmp-String-2 := "%{urlunquote:%%E,123}"
+}
+
+if (&Tmp-String-1 != &Tmp-String-0) {
test_fail
}
-if (<string>"%{urlunquote:%{request:Tmp-String-4}}" != &Tmp-String-2) {
+# Test decoding invalid encoded string
+if (&Tmp-String-2 != "") {
test_fail
}