fengyuanjs / open-tr069

Automatically exported from code.google.com/p/open-tr069
0 stars 0 forks source link

Cannot handle UINT_MAX #7

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
The function evcpe_type_validate() cannot handle the UINT_MAX 4294967295 number.
In order to reproduce, try to make a call to evcpe_attr_set() on an unsignedInt 
pareameter. The following message will be displayed:
not a positive integer: -1.

I've patched the function in order to use the strtoul() but with more check as 
suggested in one  of the site that I've visited:

int evcpe_strtoul(const char *str, int base, unsigned long *ul)
{
   char          *bad_char = NULL;
   unsigned long num = 0;

   if (!str || !ul || (base > 36) || (base < 0))
   {
      return -1;
   }

   errno = 0;
   num = strtoul(str, &bad_char, base);
   if(ERANGE == errno)
   {
      if((0 == num) && (str == bad_char))
      {
         evcpe_error(__func__, "cannot convert the string: %s", str);
      }
      else if(ULONG_MAX == num)
      {
         evcpe_error(__func__, "an overflow has been detected");
      }
   }
   else if((0 == errno) && ((NULL != bad_char) && ('\0' == *bad_char)))
   {
      *ul = num;
      return 0;
   }

   evcpe_error(__func__, "cannot convert the string: %s", str);

   return -1;
}

Original issue reported on code.google.com by atef.hal...@gmail.com on 29 Aug 2011 at 1:18

GoogleCodeExporter commented 9 years ago
I've modified the validation process of boolean and unsigned integers

int evcpe_type_validate(enum evcpe_type type, const char *value, unsigned len,
        struct evcpe_constraint *cons)
{
    int rc;
    long val;
    unsigned long uval;
    char *dup;
    struct tm tm;

    evcpe_debug(__func__, "validating value of type: %s",
            evcpe_type_to_str(type));

    switch(type) {
    case EVCPE_TYPE_STRING:
        break;
    case EVCPE_TYPE_BASE64:
        // TODO
        break;
    case EVCPE_TYPE_BOOLEAN:
    if (evcpe_strcmp(value, len, "true", 4) && evcpe_strcmp(value, len, "false", 5) &&
            evcpe_strcmp(value, len, "0", 1) && evcpe_strcmp(value, len, "1", 1)) {
         evcpe_error(__func__, "failed to convert to boolean: %.*s", len, value);
         goto finally;
        }
        break;      
    case EVCPE_TYPE_INT:
        if ((rc = evcpe_atol(value, len, &val))) {
            evcpe_error(__func__, "failed to convert to "
                    "integer: %.*s", len, value);
            goto finally;
        }
        switch(cons->type) {
        case EVCPE_CONSTRAINT_NONE:
            break;
        case EVCPE_CONSTRAINT_MIN:
        case EVCPE_CONSTRAINT_MAX:
        case EVCPE_CONSTRAINT_RANGE:
            if (cons->type != EVCPE_CONSTRAINT_MAX &&
                    val < cons->value.range.min) {
                evcpe_error(__func__, "value out of range: %ld < %ld",
                        val, cons->value.range.min);
                rc = EINVAL;
                goto finally;
            }
            if (cons->type != EVCPE_CONSTRAINT_MIN &&
                    val > cons->value.range.max) {
                evcpe_error(__func__, "value out of range: %ld > %ld",
                        val, cons->value.range.max);
                rc = EINVAL;
                goto finally;
            }
            break;
        default:
            evcpe_error(__func__, "unexpected constraint type: %d", cons->type);
            rc = EINVAL;
            goto finally;
        }
        break;
    case EVCPE_TYPE_UNSIGNED_INT:
        if ((rc = evcpe_atoul(value, len, &uval))) {
            evcpe_error(__func__, "failed to convert to "
                    "unsigned integer: %.*s", len, value);
            goto finally;
        }
        switch(cons->type) {
        case EVCPE_CONSTRAINT_NONE:
            break;
        case EVCPE_CONSTRAINT_MIN:
        case EVCPE_CONSTRAINT_MAX:
        case EVCPE_CONSTRAINT_RANGE:
            if (cons->type != EVCPE_CONSTRAINT_MAX &&
                    uval < cons->value.range.min) {
                evcpe_error(__func__, "value out of range: %ld < %ld",
                        uval, cons->value.range.min);
                rc = EINVAL;
                goto finally;
            }
            if (cons->type != EVCPE_CONSTRAINT_MIN &&
                    uval > cons->value.range.max) {
                evcpe_error(__func__, "value out of range: %ld > %ld",
                        val, cons->value.range.max);
                rc = EINVAL;
                goto finally;
            }
            break;
        default:
            evcpe_error(__func__, "unexpected constraint type: %d", cons->type);
            rc = EINVAL;
            goto finally;
        }
        break;
    case EVCPE_TYPE_DATETIME:
        if (!(dup = malloc(len + 1))) {
            evcpe_error(__func__, "failed to malloc: %d bytes", len + 1);
            rc = ENOMEM;
            goto finally;
        }
        memcpy(dup, value, len);
        dup[len] = '\0';
        if (!strptime(dup, "%Y-%m-%dT%H:%M:%S", &tm)
                && !strptime(dup, "%Y-%m-%dT%H:%M:%S%z", &tm)) {
            evcpe_error(__func__, "failed to parse dateTime: %s", dup);
            free(dup);
            rc = EINVAL;
            goto finally;
        }
        free(dup);
        break;
    case EVCPE_TYPE_UNKNOWN:
    case EVCPE_TYPE_OBJECT:
    case EVCPE_TYPE_MULTIPLE:
    default:
        evcpe_error(__func__, "value is not applicable to "
                "type: %d", type);
        rc = EINVAL;
        goto finally;
    }
    rc = 0;

finally:
    return rc;
}

Original comment by atef.hal...@gmail.com on 22 Sep 2011 at 8:36