L("||"), /* Logical operator */
);
-/** Create a valuepair from an ASCII attribute and value
- *
- * Where the attribute name is in the form:
- * - Attr-%d
- * - Attr-%d.%d.%d...
- *
- * @param ctx for talloc
- * @param dict to user for partial resolution.
- * @param attribute name to parse.
- * @param value to parse (must be a hex string).
- * @return new #fr_pair_t or NULL on error.
- */
-static fr_pair_t *fr_pair_make_unknown(TALLOC_CTX *ctx, fr_dict_t const *dict,
- char const *attribute, char const *value)
-{
- fr_pair_t *vp;
- fr_dict_attr_t *n;
- fr_sbuff_t sbuff = FR_SBUFF_IN(attribute, strlen(attribute));
-
- vp = fr_pair_alloc_null(ctx);
- if (!vp) return NULL;
-
- if ((fr_dict_unknown_afrom_oid_substr(vp, NULL, &n, fr_dict_root(dict), &sbuff, NULL) <= 0) ||
- fr_sbuff_remaining(&sbuff)) {
- error:
- talloc_free(vp);
- return NULL;
- }
- if (fr_pair_reinit_from_da(NULL, vp, n) < 0) goto error;
-
- /*
- * No value, but ensure that we still set up vp->data properly.
- */
- if (!value) {
- value = "";
-
- } else if (strncasecmp(value, "0x", 2) != 0) {
- /*
- * Unknown attributes MUST be of type 'octets'
- */
- fr_strerror_printf("Unknown attribute \"%s\" requires a hex "
- "string, not \"%s\"", attribute, value);
- goto error;
- }
-
- if (fr_pair_value_from_str(vp, value, strlen(value), &fr_value_unescape_double, false) < 0) goto error;
-
- vp->op = T_OP_EQ;
- return vp;
-}
-
-/** Create a #fr_pair_t from ASCII strings
- *
- * Converts an attribute string identifier (with an optional tag qualifier)
- * and value string into a #fr_pair_t.
- *
- * The string value is parsed according to the type of #fr_pair_t being created.
- *
- * @param[in] ctx for talloc.
- * @param[in] dict to look attributes up in.
- * @param[in] vps list where the attribute will be added (optional)
- * @param[in] attribute name.
- * @param[in] value attribute value (may be NULL if value will be set later).
- * @return a new #fr_pair_t.
- */
-fr_pair_t *fr_pair_make(TALLOC_CTX *ctx, fr_dict_t const *dict, fr_pair_list_t *vps,
- char const *attribute, char const *value)
-{
- fr_dict_attr_t const *da;
- fr_pair_t *vp;
- char const *attrname = attribute;
-
- /*
- * It's not found in the dictionary, so we use
- * another method to create the attribute.
- */
- da = fr_dict_attr_search_by_qualified_oid(NULL, dict, attrname, true, true);
- if (!da) {
- vp = fr_pair_make_unknown(ctx, dict, attrname, value);
- if (!vp) return NULL;
-
- if (vps) fr_pair_append(vps, vp);
- return vp;
- }
-
- if (da->type == FR_TYPE_GROUP) {
- fr_strerror_const("Attributes of type 'group' are not supported");
- return NULL;
- }
-
- vp = fr_pair_afrom_da(ctx, da);
- if (!vp) return NULL;
- vp->op = T_OP_EQ;
-
- /*
- * We probably want to fix fr_pair_value_from_str to accept
- * octets as values for any attribute.
- */
- if (value && (fr_pair_value_from_str(vp, value, strlen(value), &fr_value_unescape_double, false) < 0)) {
- talloc_free(vp);
- return NULL;
- }
-
- if (vps) fr_pair_append(vps, vp);
- return vp;
-}
-
/** Read one line of attribute/value pairs into a list.
*
* The line may specify multiple attributes separated by commas.
if (fr_pair_test_list_alloc(autofree, &test_pairs, NULL) < 0) goto error;
}
-/*
- * Tests functions
- */
-static void test_fr_pair_make(void)
-{
- fr_pair_t *vp;
- fr_pair_list_t list;
- TALLOC_CTX *ctx = talloc_null_ctx();
-
- fr_pair_list_init(&list);
-
- TEST_CASE("Creating 'vp' using fr_pair_make()");
- TEST_CHECK((vp = fr_pair_make(ctx, test_dict, &list, "Test-String-0", test_string)) != NULL);
-
- TEST_CASE("Validating PAIR_VERIFY()");
- PAIR_VERIFY(vp);
-
- TEST_CASE("Check (vp->vp_string == test_string)");
- TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
-
- fr_pair_list_free(&list);
-}
-
static void test_fr_pair_list_afrom_str(void)
{
fr_pair_t *vp;
/*
* Legacy calls
*/
- { "fr_pair_make", test_fr_pair_make },
{ "fr_pair_list_afrom_str", test_fr_pair_list_afrom_str },
{ "fr_pair_list_afrom_file", test_fr_pair_list_afrom_file },
{ "fr_pair_list_move_op", test_fr_pair_list_move_op },