Skip to content

Is parseInt coercion in toNumberIfNumber function intentional for matching integer-only? #74

@bparth24

Description

@bparth24

@dlongley

The toNumberIfNumber function in lib/query/util.js uses parseInt(x, 10) for numeric coercion. I wanted to check whether this is intentional to restrict coercion to integer values only, or whether it should handle decimal values and reject partially numeric strings as well.

Currently:

toNumberIfNumber("3.14")    // -> 3    (decimal truncated)
toNumberIfNumber("21abc")   // -> 21   (trailing characters ignored)

This means a credential with "score": "3.14" would match a query expecting 3, and "value": "21abc" would match a query expecting 21.

Is this the intended behavior?

Asking because I'm documenting the normative matching algorithm for QueryByExample in the VCALM specification (w3c/vcalm#574), and the answer determines whether the spec should say "integer coercion" or "numeric coercion."

If this is not intentional, the following describes the expected behavior and a suggested fix.

Expected behavior

toNumberIfNumber("3.14")   // -> 3.14  (decimal preserved)
toNumberIfNumber("21abc")  // -> "21abc" (rejected, not a valid number)

Suggested fix

Replace parseInt with Number() and a non-empty string guard:

export function toNumberIfNumber(x) {
  if(typeof x === 'number') {
    return x;
  }
  if(typeof x === 'string' && x.trim() !== '' && !isNaN(Number(x))) {
    return Number(x);
  }
  return x;
}

This ensures:

  • "21"21 (valid, preserved)
  • "3.14"3.14 (valid, decimal preserved)
  • "21abc""21abc" (rejected, not entirely numeric)
  • """" (rejected, prevents empty string matching 0)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions