Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ from [Ff][Rr][Oo][Mm]
since [Ss][Ii][Nn][Cc][Ee]
ref [Rr][Ee][Ff]
per [Pp][Ee][Rr]

nanspell ([nN][aA][nN](\([^()]*\))?)
infspell ([iI][nN][fF]([iI][nN][iI][tT][yY])?)
idchar [A-Za-z0-9_]
%Start ID_SEEN SHIFT_SEEN DATE_SEEN CLOCK_SEEN

%%
Expand All @@ -149,6 +151,12 @@ per [Pp][Ee][Rr]
_restartScanner = 0;
}

<INITIAL,SHIFT_SEEN>{sign}?{nanspell}{idchar} { yyless(0);}
<INITIAL,SHIFT_SEEN>{sign}?{infspell}{idchar} { yyless(0);}

<INITIAL,SHIFT_SEEN>{sign}?{nanspell} { yyerror("NaN is not allowed in unit expressions."); return 0; }
<INITIAL,SHIFT_SEEN>{sign}?{infspell} { yyerror("Infinity is not allowed in unit expressions."); return 0; }

<INITIAL,ID_SEEN>{space}*(@|{after}|{from}|{ref}|{since}){space}* {
BEGIN SHIFT_SEEN;
return SHIFT;
Expand Down
42 changes: 37 additions & 5 deletions prog/udunits2.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#ifndef _MSC_VER
#include <strings.h>
Expand Down Expand Up @@ -423,11 +424,42 @@ decodeInput(

ut_free(_haveUnit);

int nbytes;
if (sscanf(input, "%lg %n", &_haveUnitAmount, &nbytes) == 1) {
input += nbytes;
}
else {
int nbytes = 0;
double amt;
const char *p = input;
char *endp = NULL;

errno = 0;
amt = strtod(p, &endp);

if (endp != p) {
/* We did consume something that looks like a number? */
int next = (unsigned char)*endp;

/* If the numeric value is non-finite (NaN/Inf) ... */
if (!isfinite(amt)) {
/* ... but the next char continues an identifier, then that was not an amount.
Example: "nanosecond" -> "n" "a" "n" then "o" (identifier char).*/
if (isalpha(next) || next == '_') {
/* Treat as: no leading number; let ut_parse() see the whole string. */
_haveUnitAmount = 1;
/* DO NOT advance input. */
} else {
/* Truly a standalone non-finite amount (e.g. "nan m", "inf s") -> reject */
errMsg("NaN or Infinity is not allowed in unit expressions.");
return 0;
}
} else {
/* Finite amount is OK: Accept and advance to the remainder. */
_haveUnitAmount = amt;
input = endp;
/* Optional: skip a single ASCII space if present (traditional behavior). */
while (*input && isspace((unsigned char)*input)) {
++input;
}
}
} else {
/* No leading number parsed at all. */
_haveUnitAmount = 1;
}

Expand Down