mirror of
https://gitlab.freedesktop.org/libbsd/libbsd.git
synced 2025-05-29 23:42:42 +02:00
Update fmtcheck() from NetBSD
This commit is contained in:
parent
e3979d1a7c
commit
21edbb4f22
@ -1,3 +1,5 @@
|
|||||||
|
.\" $NetBSD: fmtcheck.3,v 1.8 2014/06/14 08:18:24 apb Exp $
|
||||||
|
.\"
|
||||||
.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
|
.\" Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -24,15 +26,12 @@
|
|||||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fmtcheck.3,v 1.9 2004/07/02 23:52:10 ru Exp $
|
.Dd June 14, 2014
|
||||||
.Dd October 16, 2002
|
|
||||||
.Os
|
|
||||||
.Dt FMTCHECK 3bsd
|
.Dt FMTCHECK 3bsd
|
||||||
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm fmtcheck
|
.Nm fmtcheck
|
||||||
.Nd sanitizes user-supplied
|
.Nd sanitizes user-supplied printf(3)-style format string
|
||||||
.Xr printf 3 Ns -style
|
|
||||||
format string
|
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
|
.ds str-Lb-libbsd Utility functions from BSD systems (libbsd, \-lbsd)
|
||||||
.Lb libbsd
|
.Lb libbsd
|
||||||
@ -45,8 +44,8 @@ for include usage.)
|
|||||||
.Fn fmtcheck "const char *fmt_suspect" "const char *fmt_default"
|
.Fn fmtcheck "const char *fmt_suspect" "const char *fmt_default"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Fn fmtcheck
|
.Nm
|
||||||
scans
|
function scans
|
||||||
.Fa fmt_suspect
|
.Fa fmt_suspect
|
||||||
and
|
and
|
||||||
.Fa fmt_default
|
.Fa fmt_default
|
||||||
@ -60,55 +59,45 @@ is a valid format string.
|
|||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Xr printf 3
|
.Xr printf 3
|
||||||
family of functions cannot verify the types of arguments that they are
|
family of functions can not verify the types of arguments that they are
|
||||||
passed at run-time.
|
passed at run-time.
|
||||||
In some cases, like
|
In some cases, like
|
||||||
.Xr catgets 3 ,
|
.Xr catgets 3 ,
|
||||||
it is useful or necessary to use a user-supplied format string with no
|
it is useful or necessary to use a user-supplied format string with no
|
||||||
guarantee that the format string matches the specified arguments.
|
guarantee that the format string matches the specified parameters.
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
.Fn fmtcheck
|
.Nm
|
||||||
was designed to be used in these cases, as in:
|
function was designed to be used in these cases, as in:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
printf(fmtcheck(user_format, standard_format), arg1, arg2);
|
printf(fmtcheck(user_format, standard_format), arg1, arg2);
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
In the check, field widths, fillers, precisions, etc.\& are ignored (unless
|
In the check, field widths, fillers, precisions, etc. are ignored (unless
|
||||||
the field width or precision is an asterisk
|
the field width or precision is an asterisk
|
||||||
.Ql *
|
.Ql *
|
||||||
instead of a digit string).
|
instead of a digit string).
|
||||||
Also, any text other than the format specifiers
|
Also, any text other than the format specifiers is completely ignored.
|
||||||
is completely ignored.
|
.Pp
|
||||||
|
Note that the formats may be quite different as long as they accept the
|
||||||
|
same parameters.
|
||||||
|
For example, "%ld %o %30s %#llx %-10.*e %n" is
|
||||||
|
compatible with "This number %lu %d%% and string %s has %qd numbers
|
||||||
|
and %.*g floats (%n)."
|
||||||
|
However, "%o" is not equivalent to "%lx" because
|
||||||
|
the first requires an integer and the second requires a long,
|
||||||
|
and "%p" is not equivalent to "%lu" because
|
||||||
|
the first requires a pointer and the second requires a long.
|
||||||
.Sh RETURN VALUES
|
.Sh RETURN VALUES
|
||||||
If
|
If
|
||||||
.Fa fmt_suspect
|
.Fa fmt_suspect
|
||||||
is a valid format and consumes the same argument types as
|
is a valid format and consumes the same argument types as
|
||||||
.Fa fmt_default ,
|
.Fa fmt_default ,
|
||||||
then the
|
then the
|
||||||
.Fn fmtcheck
|
.Nm
|
||||||
will return
|
function will return
|
||||||
.Fa fmt_suspect .
|
.Fa fmt_suspect .
|
||||||
Otherwise, it will return
|
Otherwise, it will return
|
||||||
.Fa fmt_default .
|
.Fa fmt_default .
|
||||||
.Sh SECURITY CONSIDERATIONS
|
|
||||||
Note that the formats may be quite different as long as they accept the
|
|
||||||
same arguments.
|
|
||||||
For example,
|
|
||||||
.Qq Li "%p %o %30s %#llx %-10.*e %n"
|
|
||||||
is compatible with
|
|
||||||
.Qq Li "This number %lu %d%% and string %s has %qd numbers and %.*g floats (%n)" .
|
|
||||||
However,
|
|
||||||
.Qq Li %o
|
|
||||||
is not equivalent to
|
|
||||||
.Qq Li %lx
|
|
||||||
because
|
|
||||||
the first requires an integer and the second requires a long.
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr printf 3
|
.Xr printf 3
|
||||||
.Sh BUGS
|
|
||||||
The
|
|
||||||
.Fn fmtcheck
|
|
||||||
function does not understand all of the conversions that
|
|
||||||
.Xr printf 3
|
|
||||||
does.
|
|
||||||
|
174
src/fmtcheck.c
174
src/fmtcheck.c
@ -1,3 +1,5 @@
|
|||||||
|
/* $NetBSD: fmtcheck.c,v 1.16 2017/12/13 06:43:45 rin Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -24,9 +26,6 @@
|
|||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* from NetBSD: fmtcheck.c,v 1.2 2000/11/01 01:17:20 briggs Exp
|
|
||||||
* from FreeBSD: fmtcheck.c,v 1.8 2005/03/21 08:00:55 das Exp
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
@ -35,27 +34,33 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* __weak_reference(__fmtcheck, fmtcheck); */
|
#ifdef __weak_alias
|
||||||
|
__weak_alias(fmtcheck,__fmtcheck)
|
||||||
|
#endif
|
||||||
|
|
||||||
enum __e_fmtcheck_types {
|
enum __e_fmtcheck_types {
|
||||||
FMTCHECK_START,
|
FMTCHECK_START,
|
||||||
FMTCHECK_SHORT,
|
FMTCHECK_SHORT,
|
||||||
FMTCHECK_INT,
|
FMTCHECK_INT,
|
||||||
|
FMTCHECK_WINTT,
|
||||||
FMTCHECK_LONG,
|
FMTCHECK_LONG,
|
||||||
FMTCHECK_QUAD,
|
FMTCHECK_QUAD,
|
||||||
|
FMTCHECK_INTMAXT,
|
||||||
FMTCHECK_PTRDIFFT,
|
FMTCHECK_PTRDIFFT,
|
||||||
FMTCHECK_SIZET,
|
FMTCHECK_SIZET,
|
||||||
|
FMTCHECK_POINTER,
|
||||||
|
FMTCHECK_CHARPOINTER,
|
||||||
FMTCHECK_SHORTPOINTER,
|
FMTCHECK_SHORTPOINTER,
|
||||||
FMTCHECK_INTPOINTER,
|
FMTCHECK_INTPOINTER,
|
||||||
FMTCHECK_LONGPOINTER,
|
FMTCHECK_LONGPOINTER,
|
||||||
FMTCHECK_QUADPOINTER,
|
FMTCHECK_QUADPOINTER,
|
||||||
|
FMTCHECK_INTMAXTPOINTER,
|
||||||
FMTCHECK_PTRDIFFTPOINTER,
|
FMTCHECK_PTRDIFFTPOINTER,
|
||||||
FMTCHECK_SIZETPOINTER,
|
FMTCHECK_SIZETPOINTER,
|
||||||
#ifndef NO_FLOATING_POINT
|
|
||||||
FMTCHECK_DOUBLE,
|
FMTCHECK_DOUBLE,
|
||||||
FMTCHECK_LONGDOUBLE,
|
FMTCHECK_LONGDOUBLE,
|
||||||
#endif
|
|
||||||
FMTCHECK_STRING,
|
FMTCHECK_STRING,
|
||||||
|
FMTCHECK_WSTRING,
|
||||||
FMTCHECK_WIDTH,
|
FMTCHECK_WIDTH,
|
||||||
FMTCHECK_PRECISION,
|
FMTCHECK_PRECISION,
|
||||||
FMTCHECK_DONE,
|
FMTCHECK_DONE,
|
||||||
@ -63,6 +68,18 @@ enum __e_fmtcheck_types {
|
|||||||
};
|
};
|
||||||
typedef enum __e_fmtcheck_types EFT;
|
typedef enum __e_fmtcheck_types EFT;
|
||||||
|
|
||||||
|
enum e_modifier {
|
||||||
|
MOD_NONE,
|
||||||
|
MOD_CHAR,
|
||||||
|
MOD_SHORT,
|
||||||
|
MOD_LONG,
|
||||||
|
MOD_QUAD,
|
||||||
|
MOD_INTMAXT,
|
||||||
|
MOD_LONGDOUBLE,
|
||||||
|
MOD_PTRDIFFT,
|
||||||
|
MOD_SIZET,
|
||||||
|
};
|
||||||
|
|
||||||
#define RETURN(pf,f,r) do { \
|
#define RETURN(pf,f,r) do { \
|
||||||
*(pf) = (f); \
|
*(pf) = (f); \
|
||||||
return r; \
|
return r; \
|
||||||
@ -71,103 +88,168 @@ typedef enum __e_fmtcheck_types EFT;
|
|||||||
static EFT
|
static EFT
|
||||||
get_next_format_from_precision(const char **pf)
|
get_next_format_from_precision(const char **pf)
|
||||||
{
|
{
|
||||||
int sh, lg, quad, longdouble, ptrdifft, sizet;
|
enum e_modifier modifier;
|
||||||
const char *f;
|
const char *f;
|
||||||
|
|
||||||
sh = lg = quad = longdouble = ptrdifft = sizet = 0;
|
|
||||||
|
|
||||||
f = *pf;
|
f = *pf;
|
||||||
switch (*f) {
|
switch (*f) {
|
||||||
case 'h':
|
case 'h':
|
||||||
f++;
|
f++;
|
||||||
sh = 1;
|
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
|
if (*f == 'h') {
|
||||||
|
f++;
|
||||||
|
modifier = MOD_CHAR;
|
||||||
|
} else {
|
||||||
|
modifier = MOD_SHORT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
f++;
|
||||||
|
modifier = MOD_INTMAXT;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
f++;
|
f++;
|
||||||
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
if (*f == 'l') {
|
if (*f == 'l') {
|
||||||
f++;
|
f++;
|
||||||
quad = 1;
|
modifier = MOD_QUAD;
|
||||||
} else {
|
} else {
|
||||||
lg = 1;
|
modifier = MOD_LONG;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
f++;
|
f++;
|
||||||
quad = 1;
|
modifier = MOD_QUAD;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
f++;
|
f++;
|
||||||
ptrdifft = 1;
|
modifier = MOD_PTRDIFFT;
|
||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
f++;
|
f++;
|
||||||
sizet = 1;
|
modifier = MOD_SIZET;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
f++;
|
f++;
|
||||||
longdouble = 1;
|
modifier = MOD_LONGDOUBLE;
|
||||||
break;
|
break;
|
||||||
|
#ifdef WIN32
|
||||||
|
case 'I':
|
||||||
|
f++;
|
||||||
|
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
|
if (*f == '3' && f[1] == '2') {
|
||||||
|
f += 2;
|
||||||
|
modifier = MOD_NONE;
|
||||||
|
} else if (*f == '6' && f[1] == '4') {
|
||||||
|
f += 2;
|
||||||
|
modifier = MOD_QUAD;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef _WIN64
|
||||||
|
modifier = MOD_QUAD;
|
||||||
|
#else
|
||||||
|
modifier = MOD_NONE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
|
modifier = MOD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
if (strchr("diouxX", *f)) {
|
if (strchr("diouxX", *f)) {
|
||||||
if (longdouble)
|
switch (modifier) {
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
case MOD_LONG:
|
||||||
if (lg)
|
|
||||||
RETURN(pf,f,FMTCHECK_LONG);
|
RETURN(pf,f,FMTCHECK_LONG);
|
||||||
if (quad)
|
case MOD_QUAD:
|
||||||
RETURN(pf,f,FMTCHECK_QUAD);
|
RETURN(pf,f,FMTCHECK_QUAD);
|
||||||
if (ptrdifft)
|
case MOD_INTMAXT:
|
||||||
|
RETURN(pf,f,FMTCHECK_INTMAXT);
|
||||||
|
case MOD_PTRDIFFT:
|
||||||
RETURN(pf,f,FMTCHECK_PTRDIFFT);
|
RETURN(pf,f,FMTCHECK_PTRDIFFT);
|
||||||
if (sizet)
|
case MOD_SIZET:
|
||||||
RETURN(pf,f,FMTCHECK_SIZET);
|
RETURN(pf,f,FMTCHECK_SIZET);
|
||||||
RETURN(pf,f,FMTCHECK_INT);
|
case MOD_CHAR:
|
||||||
|
case MOD_SHORT:
|
||||||
|
case MOD_NONE:
|
||||||
|
RETURN(pf,f,FMTCHECK_INT);
|
||||||
|
default:
|
||||||
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (*f == 'n') {
|
if (*f == 'n') {
|
||||||
if (longdouble)
|
switch (modifier) {
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
case MOD_CHAR:
|
||||||
if (sh)
|
RETURN(pf,f,FMTCHECK_CHARPOINTER);
|
||||||
|
case MOD_SHORT:
|
||||||
RETURN(pf,f,FMTCHECK_SHORTPOINTER);
|
RETURN(pf,f,FMTCHECK_SHORTPOINTER);
|
||||||
if (lg)
|
case MOD_LONG:
|
||||||
RETURN(pf,f,FMTCHECK_LONGPOINTER);
|
RETURN(pf,f,FMTCHECK_LONGPOINTER);
|
||||||
if (quad)
|
case MOD_QUAD:
|
||||||
RETURN(pf,f,FMTCHECK_QUADPOINTER);
|
RETURN(pf,f,FMTCHECK_QUADPOINTER);
|
||||||
if (ptrdifft)
|
case MOD_INTMAXT:
|
||||||
|
RETURN(pf,f,FMTCHECK_INTMAXTPOINTER);
|
||||||
|
case MOD_PTRDIFFT:
|
||||||
RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
|
RETURN(pf,f,FMTCHECK_PTRDIFFTPOINTER);
|
||||||
if (sizet)
|
case MOD_SIZET:
|
||||||
RETURN(pf,f,FMTCHECK_SIZETPOINTER);
|
RETURN(pf,f,FMTCHECK_SIZETPOINTER);
|
||||||
RETURN(pf,f,FMTCHECK_INTPOINTER);
|
case MOD_NONE:
|
||||||
|
RETURN(pf,f,FMTCHECK_INTPOINTER);
|
||||||
|
default:
|
||||||
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (strchr("DOU", *f)) {
|
if (strchr("DOU", *f)) {
|
||||||
if (sh + lg + quad + longdouble + ptrdifft + sizet)
|
if (modifier != MOD_NONE)
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
RETURN(pf,f,FMTCHECK_LONG);
|
RETURN(pf,f,FMTCHECK_LONG);
|
||||||
}
|
}
|
||||||
#ifndef NO_FLOATING_POINT
|
|
||||||
if (strchr("aAeEfFgG", *f)) {
|
if (strchr("aAeEfFgG", *f)) {
|
||||||
if (longdouble)
|
switch (modifier) {
|
||||||
|
case MOD_LONGDOUBLE:
|
||||||
RETURN(pf,f,FMTCHECK_LONGDOUBLE);
|
RETURN(pf,f,FMTCHECK_LONGDOUBLE);
|
||||||
if (sh + lg + quad + ptrdifft + sizet)
|
case MOD_LONG:
|
||||||
|
case MOD_NONE:
|
||||||
|
RETURN(pf,f,FMTCHECK_DOUBLE);
|
||||||
|
default:
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
RETURN(pf,f,FMTCHECK_DOUBLE);
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (*f == 'c') {
|
if (*f == 'c') {
|
||||||
if (sh + lg + quad + longdouble + ptrdifft + sizet)
|
switch (modifier) {
|
||||||
|
case MOD_LONG:
|
||||||
|
RETURN(pf,f,FMTCHECK_WINTT);
|
||||||
|
case MOD_NONE:
|
||||||
|
RETURN(pf,f,FMTCHECK_INT);
|
||||||
|
default:
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
RETURN(pf,f,FMTCHECK_INT);
|
}
|
||||||
|
}
|
||||||
|
if (*f == 'C') {
|
||||||
|
if (modifier != MOD_NONE)
|
||||||
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
|
RETURN(pf,f,FMTCHECK_WINTT);
|
||||||
}
|
}
|
||||||
if (*f == 's') {
|
if (*f == 's') {
|
||||||
if (sh + lg + quad + longdouble + ptrdifft + sizet)
|
switch (modifier) {
|
||||||
|
case MOD_LONG:
|
||||||
|
RETURN(pf,f,FMTCHECK_WSTRING);
|
||||||
|
case MOD_NONE:
|
||||||
|
RETURN(pf,f,FMTCHECK_STRING);
|
||||||
|
default:
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
RETURN(pf,f,FMTCHECK_STRING);
|
}
|
||||||
|
}
|
||||||
|
if (*f == 'S') {
|
||||||
|
if (modifier != MOD_NONE)
|
||||||
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
|
RETURN(pf,f,FMTCHECK_WSTRING);
|
||||||
}
|
}
|
||||||
if (*f == 'p') {
|
if (*f == 'p') {
|
||||||
if (sh + lg + quad + longdouble + ptrdifft + sizet)
|
if (modifier != MOD_NONE)
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
RETURN(pf,f,FMTCHECK_LONG);
|
RETURN(pf,f,FMTCHECK_POINTER);
|
||||||
}
|
}
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
@ -185,7 +267,7 @@ get_next_format_from_width(const char **pf)
|
|||||||
RETURN(pf,f,FMTCHECK_PRECISION);
|
RETURN(pf,f,FMTCHECK_PRECISION);
|
||||||
}
|
}
|
||||||
/* eat any precision (empty is allowed) */
|
/* eat any precision (empty is allowed) */
|
||||||
while (isdigit(*f)) f++;
|
while (isdigit((unsigned char)*f)) f++;
|
||||||
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
if (!*f) RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
}
|
}
|
||||||
RETURN(pf,f,get_next_format_from_precision(pf));
|
RETURN(pf,f,get_next_format_from_precision(pf));
|
||||||
@ -229,7 +311,7 @@ get_next_format(const char **pf, EFT eft)
|
|||||||
RETURN(pf,f,FMTCHECK_WIDTH);
|
RETURN(pf,f,FMTCHECK_WIDTH);
|
||||||
}
|
}
|
||||||
/* eat any width */
|
/* eat any width */
|
||||||
while (isdigit(*f)) f++;
|
while (isdigit((unsigned char)*f)) f++;
|
||||||
if (!*f) {
|
if (!*f) {
|
||||||
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
RETURN(pf,f,FMTCHECK_UNKNOWN);
|
||||||
}
|
}
|
||||||
@ -238,7 +320,7 @@ get_next_format(const char **pf, EFT eft)
|
|||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
__const char *
|
const char *
|
||||||
fmtcheck(const char *f1, const char *f2)
|
fmtcheck(const char *f1, const char *f2)
|
||||||
{
|
{
|
||||||
const char *f1p, *f2p;
|
const char *f1p, *f2p;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user