* [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF
2022-12-01 2:51 [LTP] [PATCH v2 0/2] Add handling of abnormal input for parse_opts() Zhao Gongyi via ltp
@ 2022-12-01 2:51 ` Zhao Gongyi via ltp
2022-12-01 13:42 ` Cyril Hrubis
0 siblings, 1 reply; 6+ messages in thread
From: Zhao Gongyi via ltp @ 2022-12-01 2:51 UTC (permalink / raw)
To: ltp
Add a new macro SAFE_STRTOF, which is a safe mode of strtof().
Signed-off-by: Zhao Gongyi <zhaogongyi@huawei.com>
---
include/safe_macros_fn.h | 3 +++
include/tst_safe_macros.h | 3 +++
lib/safe_macros.c | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 40 insertions(+)
diff --git a/include/safe_macros_fn.h b/include/safe_macros_fn.h
index 114d8fd43..d256091b7 100644
--- a/include/safe_macros_fn.h
+++ b/include/safe_macros_fn.h
@@ -133,6 +133,9 @@ unsigned long safe_strtoul(const char *file, const int lineno,
void (cleanup_fn)(void),
char *str, unsigned long min, unsigned long max);
+float safe_strtof(const char *file, const int lineno,
+ void (cleanup_fn)(void), char *str, float min, float max);
+
long safe_sysconf(const char *file, const int lineno,
void (cleanup_fn)(void), int name);
diff --git a/include/tst_safe_macros.h b/include/tst_safe_macros.h
index ab00dd14a..0cf3d7878 100644
--- a/include/tst_safe_macros.h
+++ b/include/tst_safe_macros.h
@@ -186,6 +186,9 @@ int safe_getgroups(const char *file, const int lineno, int size, gid_t list[]);
#define SAFE_STRTOUL(str, min, max) \
safe_strtoul(__FILE__, __LINE__, NULL, (str), (min), (max))
+#define SAFE_STRTOF(str, min, max) \
+ safe_strtof(__FILE__, __LINE__, NULL, (str), (min), (max))
+
#define SAFE_SYSCONF(name) \
safe_sysconf(__FILE__, __LINE__, NULL, name)
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index d8816631f..d00336748 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
+#include <math.h>
#include "test.h"
#include "safe_macros.h"
@@ -629,6 +630,39 @@ unsigned long safe_strtoul(const char *file, const int lineno,
return rval;
}
+float safe_strtof(const char *file, const int lineno,
+ void (cleanup_fn) (void), char *str,
+ float min, float max)
+{
+ float rval;
+ char *endptr;
+
+ errno = 0;
+ rval = strtof(str, &endptr);
+
+ if ((errno == ERANGE) || (rval == 0)
+ || (rval == HUGE_VAL) || (rval == -HUGE_VAL)) {
+ tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
+ "strtof(%s) failed", str);
+ return rval;
+ }
+
+ if (rval > max || rval < min) {
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "strtof(%s): %f is out of range %f - %f",
+ str, rval, min, max);
+ return 0;
+ }
+
+ if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "Invalid value: '%s'", str);
+ return 0;
+ }
+
+ return rval;
+}
+
long safe_sysconf(const char *file, const int lineno,
void (cleanup_fn) (void), int name)
{
--
2.17.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF
2022-12-01 2:51 ` [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF Zhao Gongyi via ltp
@ 2022-12-01 13:42 ` Cyril Hrubis
0 siblings, 0 replies; 6+ messages in thread
From: Cyril Hrubis @ 2022-12-01 13:42 UTC (permalink / raw)
To: Zhao Gongyi; +Cc: ltp
Hi!
> +float safe_strtof(const char *file, const int lineno,
> + void (cleanup_fn) (void), char *str,
> + float min, float max)
> +{
> + float rval;
> + char *endptr;
> +
> + errno = 0;
> + rval = strtof(str, &endptr);
> +
> + if ((errno == ERANGE) || (rval == 0)
> + || (rval == HUGE_VAL) || (rval == -HUGE_VAL)) {
This does not look right, supposedly the ERANGE is only set on overflow,
and the rval is not guaranteed to be exact on underflow. Also rval == 0
is a valid result.
We do zero errno above so I would just do:
if (errno) {
tst_brkm_(...);
return rval;
}
> + tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
> + "strtof(%s) failed", str);
> + return rval;
> + }
> +
> + if (rval > max || rval < min) {
> + tst_brkm_(file, lineno, TBROK, cleanup_fn,
> + "strtof(%s): %f is out of range %f - %f",
> + str, rval, min, max);
> + return 0;
> + }
> +
> + if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
> + tst_brkm_(file, lineno, TBROK, cleanup_fn,
> + "Invalid value: '%s'", str);
> + return 0;
> + }
> +
> + return rval;
> +}
Otherwise it looks good.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF
@ 2022-12-02 2:34 zhaogongyi via ltp
2022-12-02 10:37 ` Cyril Hrubis
0 siblings, 1 reply; 6+ messages in thread
From: zhaogongyi via ltp @ 2022-12-02 2:34 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp@lists.linux.it
Hi Cyril,
>
> Hi!
> > +float safe_strtof(const char *file, const int lineno,
> > + void (cleanup_fn) (void), char *str,
> > + float min, float max)
> > +{
> > + float rval;
> > + char *endptr;
> > +
> > + errno = 0;
> > + rval = strtof(str, &endptr);
> > +
> > + if ((errno == ERANGE) || (rval == 0)
> > + || (rval == HUGE_VAL) || (rval == -HUGE_VAL)) {
>
> This does not look right, supposedly the ERANGE is only set on overflow,
> and the rval is not guaranteed to be exact on underflow. Also rval == 0 is a
> valid result.
>
According to man 3 strtof, it seems there are some cases like:
1. strtof return the converted value as normal
2. strtof return 0 when no conversion is performed, and endptr == nptr: 'rval == 0'
3. strtof return HUGE_VAL or -HUGE_VAL when overflow: '(rval == HUGE_VAL) || (rval == -HUGE_VAL)'
4. strtof retrun 0 and set errno to ERANGE when underflow: 'errno == ERANGE'
For 2, it seems need to add checking of endptr when 'rval == 0' like: (rval == 0 && !strcmp(endptr, nptr)
Other places seem to be fine.
Regards,
Gongyi
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF
@ 2022-12-02 2:54 zhaogongyi via ltp
0 siblings, 0 replies; 6+ messages in thread
From: zhaogongyi via ltp @ 2022-12-02 2:54 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp@lists.linux.it
Hi Cyril,
>
> > Hi!
> > > +float safe_strtof(const char *file, const int lineno,
> > > + void (cleanup_fn) (void), char *str,
> > > + float min, float max)
> > > +{
> > > + float rval;
> > > + char *endptr;
> > > +
> > > + errno = 0;
> > > + rval = strtof(str, &endptr);
> > > +
> > > + if ((errno == ERANGE) || (rval == 0)
> > > + || (rval == HUGE_VAL) || (rval == -HUGE_VAL)) {
> >
> > This does not look right, supposedly the ERANGE is only set on
> > overflow, and the rval is not guaranteed to be exact on underflow.
> > Also rval == 0 is a valid result.
> >
>
> According to man 3 strtof, it seems there are some cases like:
>
> 1. strtof return the converted value as normal 2. strtof return 0 when no
> conversion is performed, and endptr == nptr: 'rval == 0'
> 3. strtof return HUGE_VAL or -HUGE_VAL when overflow: '(rval ==
> HUGE_VAL) || (rval == -HUGE_VAL)'
> 4. strtof retrun 0 and set errno to ERANGE when underflow: 'errno ==
> ERANGE'
>
>
> For 2, it seems need to add checking of endptr when 'rval == 0' like: (rval
> == 0 && !strcmp(endptr, nptr)
>
> Other places seem to be fine.
>
>
The exception cases may be described as:
1. strtof return 0 when no conversion is performed, and endptr == nptr: 'rval == 0 && !strcmp(endptr, nptr)'
2. strtof return HUGE_VAL or -HUGE_VAL when overflow: '((rval ==HUGE_VAL) || (rval == -HUGE_VAL)) && errno == ERANGE'
3. strtof retrun 0 and set errno to ERANGE when underflow: 'errno ==ERANGE && rval == 0'
So it may be write as:
If (( errno == ERANGE && (rval == HUGE_VAL || rval == -HUGE_VAL || rval == 0))
|| (rval == 0 && !strcmp(endptr, nptr)))
If the description as above is ok, I will resubmit the patch.
Regards,
Gongyi
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF
2022-12-02 2:34 zhaogongyi via ltp
@ 2022-12-02 10:37 ` Cyril Hrubis
0 siblings, 0 replies; 6+ messages in thread
From: Cyril Hrubis @ 2022-12-02 10:37 UTC (permalink / raw)
To: zhaogongyi; +Cc: ltp@lists.linux.it
Hi!
> According to man 3 strtof, it seems there are some cases like:
>
> 1. strtof return the converted value as normal
> 2. strtof return 0 when no conversion is performed, and endptr == nptr: 'rval == 0'
We can ignore this case since we check that the string was consumed
later on. That's the:
+ if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "Invalid value: '%s'", str);
+ return 0;
+ }
> 3. strtof return HUGE_VAL or -HUGE_VAL when overflow: '(rval == HUGE_VAL) || (rval == -HUGE_VAL)'
> 4. strtof retrun 0 and set errno to ERANGE when underflow: 'errno == ERANGE'
My manual says that the value is no larger than DBL_MIN, FLT_MIN, or
LDBL_MIN in this case. Either way I would avoid checking the returned
value in the case errno was set.
> For 2, it seems need to add checking of endptr when 'rval == 0' like: (rval == 0 && !strcmp(endptr, nptr)
Again, no need to check the actual return value, we can just check that
the string was consumed, which we already do.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF
@ 2022-12-05 7:03 zhaogongyi via ltp
0 siblings, 0 replies; 6+ messages in thread
From: zhaogongyi via ltp @ 2022-12-05 7:03 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp@lists.linux.it
Hi Cyril,
>
> Hi!
> > According to man 3 strtof, it seems there are some cases like:
> >
> > 1. strtof return the converted value as normal 2. strtof return 0 when
> > no conversion is performed, and endptr == nptr: 'rval == 0'
>
> We can ignore this case since we check that the string was consumed later
> on. That's the:
>
> + if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
> + tst_brkm_(file, lineno, TBROK, cleanup_fn,
> + "Invalid value: '%s'", str);
> + return 0;
> + }
>
>
> > 3. strtof return HUGE_VAL or -HUGE_VAL when overflow: '(rval ==
> HUGE_VAL) || (rval == -HUGE_VAL)'
> > 4. strtof retrun 0 and set errno to ERANGE when underflow: 'errno ==
> ERANGE'
>
> My manual says that the value is no larger than DBL_MIN, FLT_MIN, or
> LDBL_MIN in this case. Either way I would avoid checking the returned
> value in the case errno was set.
I usually look for information here: https://pubs.opengroup.org/onlinepubs/9699919799/
>
> > For 2, it seems need to add checking of endptr when 'rval == 0' like:
> > (rval == 0 && !strcmp(endptr, nptr)
>
> Again, no need to check the actual return value, we can just check that the
> string was consumed, which we already do.
>
Thanks! I have resubmit the patch as your suggestion.
Regards,
Gongyi
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-12-05 7:04 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-05 7:03 [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF zhaogongyi via ltp
-- strict thread matches above, loose matches on Subject: below --
2022-12-02 2:54 zhaogongyi via ltp
2022-12-02 2:34 zhaogongyi via ltp
2022-12-02 10:37 ` Cyril Hrubis
2022-12-01 2:51 [LTP] [PATCH v2 0/2] Add handling of abnormal input for parse_opts() Zhao Gongyi via ltp
2022-12-01 2:51 ` [LTP] [PATCH v2 1/2] lib/safe_macros: Add SAFE_STRTOF Zhao Gongyi via ltp
2022-12-01 13:42 ` Cyril Hrubis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox