ib_status_t ib_string_to_num_ex( const char *s, size_t slen, int base, ib_num_t *result ) { assert(result != NULL); char *buf; ib_status_t rc; /* Check for zero length string */ if ( (s == NULL) || (slen == 0) ) { return IB_EINVAL; } buf = malloc(slen+1); if (buf == NULL) { return IB_EALLOC; } memcpy(buf, s, slen); buf[slen] = '\0'; rc = ib_string_to_num(buf, base, result); free(buf); return rc; }
/** * Attempt to convert a single field. * * If the desired type matches the in_field type, out_field is set to NULL * and IB_OK is returned. * * @param[in,out] mp Memory pool to use. * @param[in] desired_type The type to try to convert this to. * @param[in] in_field The input field. * @param[out] out_field The output field to write to. * * @returns * - IB_OK On success. * - IB_EINVAL If a string cannot be converted to a number type * or some other invalid type conversion is requested. * - IB_EALLOC Memory allocation error. */ ib_status_t ib_field_convert( ib_mpool_t *mp, const ib_ftype_t desired_type, const ib_field_t *in_field, ib_field_t **out_field) { assert(mp); assert(in_field); ib_status_t rc; /* Holder values for in_field values before being set in out_field. */ size_t sz; const char *str; const ib_bytestr_t *bstr; ib_num_t num; ib_float_t flt; void *new_field_value; if (in_field->type == desired_type) { *out_field = NULL; return IB_OK; } switch (in_field->type) { case IB_FTYPE_NULSTR: /* Extract string. */ rc = ib_field_value(in_field, ib_ftype_nulstr_out(&str)); if (rc!=IB_OK){ return rc; } switch(desired_type) { case IB_FTYPE_BYTESTR: rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc!=IB_OK){ return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_NUM: rc = ib_string_to_num(str, 0, &num); new_field_value = ib_ftype_num_in(&num); break; case IB_FTYPE_FLOAT: rc = ib_string_to_float(str, &flt); new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_BYTESTR: /* Extract bytestr. */ rc = ib_field_value(in_field, ib_ftype_bytestr_out(&bstr)); if (rc!=IB_OK){ return rc; } sz = ib_bytestr_length(bstr); /* Convert byte str. */ switch(desired_type) { case IB_FTYPE_NULSTR: str = ib_mpool_memdup_to_str(mp, bstr, sz); if (!str) { return rc; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_NUM: rc = ib_string_to_num_ex((char *)bstr, sz, 0, &num); new_field_value = ib_ftype_num_in(&num); break; case IB_FTYPE_FLOAT: rc = ib_string_to_float_ex((char *)bstr, sz, &flt); new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_NUM: /* Extract unum. */ rc = ib_field_value(in_field, ib_ftype_num_out(&num)); if (rc!=IB_OK){ return rc; } switch(desired_type) { case IB_FTYPE_NULSTR: str = ib_num_to_string(mp, num); if (!str) { return IB_EINVAL; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_BYTESTR: str = ib_num_to_string(mp, num); if (!str) { return IB_EINVAL; } rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc!=IB_OK){ return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_FLOAT: flt = (ib_float_t)num; new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_FLOAT: /* Extract unum. */ rc = ib_field_value(in_field, ib_ftype_float_out(&flt)); if (rc!=IB_OK){ return rc; } switch(desired_type) { case IB_FTYPE_NULSTR: str = ib_float_to_string(mp, flt); if (!str) { return IB_EINVAL; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_BYTESTR: str = ib_float_to_string(mp, flt); if (!str) { return IB_EINVAL; } rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc!=IB_OK){ return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_NUM: num = (ib_float_t)flt; new_field_value = ib_ftype_num_in(&num); break; default: return IB_EINVAL; } break; default: return IB_EINVAL; } rc = ib_field_create( out_field, mp, in_field->name, in_field->nlen, desired_type, new_field_value); return rc; }
/** * Handle single parameter directives. * * @param cp Config parser * @param name Directive name * @param p1 First parameter * @param cbdata Callback data (from directive registration) * * @returns Status code */ static ib_status_t handle_directive_param(ib_cfgparser_t *cp, const char *name, const char *p1, void *cbdata) { assert(cp != NULL); assert(name != NULL); assert(p1 != NULL); assert(cp->ib != NULL); ib_engine_t *ib = cp->ib; ib_status_t rc; ib_module_t *module = NULL; modpcre_cfg_t *config = NULL; ib_context_t *ctx = cp->cur_ctx ? cp->cur_ctx : ib_context_main(ib); const char *pname; ib_num_t value; /* Get my module object */ rc = ib_engine_module_get(cp->ib, MODULE_NAME_STR, &module); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to get %s module object: %s", MODULE_NAME_STR, ib_status_to_string(rc)); return rc; } /* Get my module configuration */ rc = ib_context_module_config(ctx, module, (void *)&config); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to get %s module configuration: %s", MODULE_NAME_STR, ib_status_to_string(rc)); return rc; } /* p1 should be a number */ rc = ib_string_to_num(p1, 0, &value); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to convert \"%s\" to a number for \"%s\": %s", p1, name, ib_status_to_string(rc)); return rc; } if (strcasecmp("PcreMatchLimit", name) == 0) { pname = "pcre.match_limit"; } else if (strcasecmp("PcreMatchLimitRecursion", name) == 0) { pname = "pcre.match_limit_recursion"; } else if (strcasecmp("PcreJitStackStart", name) == 0) { pname = "pcre.jit_stack_start"; } else if (strcasecmp("PcreJitStackMax", name) == 0) { pname = "pcre.jit_stack_max"; } else if (strcasecmp("PcreDfaWorkspaceSize", name) == 0) { pname = "pcre.dfa_workspace_size"; } else { ib_cfg_log_error(cp, "Unhandled directive \"%s\"", name); return IB_EINVAL; } rc = ib_context_set_num(ctx, pname, value); if (rc != IB_OK) { ib_cfg_log_error(cp, "Failed to set \"%s\" to %ld for \"%s\": %s", pname, (long int)value, name, ib_status_to_string(rc)); } return IB_OK; }
static ib_status_t field_from_string_internal( ib_mpool_t *mp, const char *name, size_t nlen, const char *vstr, size_t vlen, bool vstr_is_nulstr, ib_field_t **pfield) { assert(mp != NULL); assert(name != NULL); assert(vstr != NULL); assert(pfield != NULL); ib_status_t conv; ib_status_t rc = IB_OK; ib_field_t *field; *pfield = NULL; /* Try to convert to an integer */ if (*pfield == NULL) { ib_num_t num_val; if (vstr_is_nulstr) { conv = ib_string_to_num(vstr, 0, &num_val); } else { conv = ib_string_to_num_ex(vstr, vlen, 0, &num_val); } if (conv == IB_OK) { rc = ib_field_create(&field, mp, name, nlen, IB_FTYPE_NUM, ib_ftype_num_in(&num_val)); *pfield = field; } } /* Try to convert to a float */ if (*pfield == NULL) { ib_float_t float_val; if (vstr_is_nulstr) { conv = ib_string_to_float(vstr, &float_val); } else { conv = ib_string_to_float_ex(vstr, vlen, &float_val); } if (conv == IB_OK) { rc = ib_field_create(&field, mp, name, nlen, IB_FTYPE_FLOAT, ib_ftype_float_in(&float_val)); *pfield = field; } } /* Finally, assume that it's a string */ if (*pfield == NULL) { if (vstr_is_nulstr) { rc = ib_field_create(&field, mp, name, nlen, IB_FTYPE_NULSTR, ib_ftype_nulstr_in(vstr)); } else { ib_bytestr_t *bs; rc = ib_bytestr_dup_mem(&bs, mp, (const uint8_t *)vstr, vlen); if (rc != IB_OK) { return rc; } rc = ib_field_create(&field, mp, name, nlen, IB_FTYPE_BYTESTR, ib_ftype_bytestr_in(bs)); } *pfield = field; } return rc; }
ib_status_t ib_field_convert( ib_mpool_t *mp, const ib_ftype_t desired_type, const ib_field_t *in_field, ib_field_t **out_field ) { assert(mp); assert(in_field); ib_status_t rc; /* Holder values for in_field values before being set in out_field. */ size_t sz; const char *str; const ib_bytestr_t *bstr; ib_num_t num; ib_time_t tme; ib_float_t flt; void *new_field_value; if (in_field->type == desired_type) { *out_field = NULL; return IB_OK; } switch (in_field->type) { case IB_FTYPE_NULSTR: /* Extract string. Note that a zero-length nulstr field can * have a NULL value in the union. */ if ( (in_field->val->u.nulstr == NULL) && (in_field->val->pval == NULL) ) { str = ""; } else { rc = ib_field_value(in_field, ib_ftype_nulstr_out(&str)); if (rc != IB_OK){ return rc; } } switch (desired_type) { case IB_FTYPE_BYTESTR: rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_TIME: rc = ib_string_to_time(str, &tme); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_time_in(&tme); break; case IB_FTYPE_NUM: rc = ib_string_to_num(str, 0, &num); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_num_in(&num); break; case IB_FTYPE_FLOAT: rc = ib_string_to_float(str, &flt); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_BYTESTR: /* Extract bytestr. */ rc = ib_field_value(in_field, ib_ftype_bytestr_out(&bstr)); if (rc != IB_OK){ return rc; } str = (const char *)ib_bytestr_const_ptr(bstr); sz = ib_bytestr_length(bstr); /* Convert byte str. */ switch(desired_type) { case IB_FTYPE_NULSTR: str = ib_mpool_memdup_to_str(mp, str, sz); if (!str) { return rc; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_TIME: rc = ib_string_to_time_ex(str, sz, &tme); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_time_in(&tme); break; case IB_FTYPE_NUM: rc = ib_string_to_num_ex(str, sz, 0, &num); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_num_in(&num); break; case IB_FTYPE_FLOAT: rc = ib_string_to_float_ex(str, sz, &flt); if (rc != IB_OK) { return rc; } new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_TIME: /* Extract time. */ rc = ib_field_value(in_field, ib_ftype_time_out(&tme)); if (rc != IB_OK){ return rc; } switch (desired_type) { case IB_FTYPE_NULSTR: str = ib_time_to_string(mp, tme); if (! str) { return IB_EINVAL; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_BYTESTR: str = ib_time_to_string(mp, tme); if (! str) { return IB_EINVAL; } rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc != IB_OK){ return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_FLOAT: flt = (ib_float_t)tme; /* Check that our assignment is within error=1, or fail. */ if (llabs(tme - flt) > 1) { return IB_EINVAL; } new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_NUM: /* Extract unum. */ rc = ib_field_value(in_field, ib_ftype_num_out(&num)); if (rc != IB_OK){ return rc; } switch (desired_type) { case IB_FTYPE_NULSTR: str = ib_num_to_string(mp, num); if (! str) { return IB_EINVAL; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_BYTESTR: str = ib_num_to_string(mp, num); if (! str) { return IB_EINVAL; } rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc != IB_OK){ return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_TIME: if (num < 0) { return IB_EINVAL; } tme = (ib_time_t)num; new_field_value = ib_ftype_time_in(&tme); break; case IB_FTYPE_FLOAT: flt = (ib_float_t)num; if (llabs(flt - num) > 1) { return IB_EINVAL; } new_field_value = ib_ftype_float_in(&flt); break; default: return IB_EINVAL; } break; case IB_FTYPE_FLOAT: /* Extract unum. */ rc = ib_field_value(in_field, ib_ftype_float_out(&flt)); if (rc != IB_OK){ return rc; } switch (desired_type) { case IB_FTYPE_NULSTR: str = ib_float_to_string(mp, flt); if (!str) { return IB_EINVAL; } new_field_value = ib_ftype_nulstr_in(str); break; case IB_FTYPE_BYTESTR: str = ib_float_to_string(mp, flt); if (!str) { return IB_EINVAL; } rc = ib_bytestr_dup_nulstr((ib_bytestr_t **)&bstr, mp, str); if (rc != IB_OK){ return rc; } new_field_value = ib_ftype_bytestr_in(bstr); break; case IB_FTYPE_TIME: if (flt < 0) { return IB_EINVAL; } tme = (ib_float_t)flt; new_field_value = ib_ftype_time_in(&tme); break; case IB_FTYPE_NUM: num = (ib_float_t)flt; new_field_value = ib_ftype_num_in(&num); break; default: return IB_EINVAL; } break; default: return IB_EINVAL; } rc = ib_field_create( out_field, mp, in_field->name, in_field->nlen, desired_type, new_field_value ); return rc; }