improve on 'auto' mode for DISABLE_PERCENT_ZT (#28)

Visual Studio 2013 includes support for %zu and %td, so let newer
versions of it avoid the fallback, and while at it, make sure that
the first check is for DISABLE_PERCENT_ZT so it will be always
honoured if chosen.

prtdiff_t is signed, so use a signed type instead, and make sure
that an appropiate width is chosen if pointers are 64bit wide.

Remove the need for the size_t cast and instead change the size
of the equivalent format identifier to avoid truncations.
This commit is contained in:
Carlo Marcelo Arenas Belón 2021-10-29 06:29:47 -07:00 committed by GitHub
parent c99f0738c5
commit d46f1863be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 40 deletions

View File

@ -563,15 +563,16 @@ documentation.
.sp
The C99 standard defines formatting modifiers z and t for size_t and
ptrdiff_t values, respectively. By default, PCRE2 uses these modifiers in
environments other than Microsoft Visual Studio when __STDC_VERSION__ is
defined and has a value greater than or equal to 199901L (indicating C99).
environments other than old versions of Microsoft Visual Studio when
__STDC_VERSION__ is defined and has a value greater than or equal to 199901L
(indicating support for C99).
However, there is at least one environment that claims to be C99 but does not
support these modifiers. If
.sp
--disable-percent-zt
.sp
is specified, no use is made of the z or t modifiers. Instead of %td or %zu,
%lu is used, with a cast for size_t values.
a suitable format is used depending in the size of long for the platform.
.
.
.SH "SUPPORT FOR FUZZERS"

View File

@ -110,17 +110,18 @@ MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */
#define snprintf _snprintf
#endif
/* VC and older compilers don't support %td or %zu, and even some that claim to
/* old VC and older compilers don't support %td or %zu, and even some that claim to
be C99 don't support it (hence DISABLE_PERCENT_ZT). */
#if defined(_MSC_VER) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || defined(DISABLE_PERCENT_ZT)
#define PTR_FORM "lu"
#define SIZ_FORM "lu"
#define SIZ_CAST (unsigned long int)
#if defined(DISABLE_PERCENT_ZT) || (defined(_MSC_VER) && (_MSC_VER < 1800)) || \
(!defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L))
#ifdef _WIN64
#define SIZ_FORM "llu"
#else
#define SIZ_FORM "lu"
#endif
#else
#define PTR_FORM "td"
#define SIZ_FORM "zu"
#define SIZ_CAST
#endif
#define FALSE 0
@ -1856,8 +1857,7 @@ for (i = 1; p != NULL; p = p->next, i++)
unsigned char mbuffer[256];
PCRE2_SIZE startchar = pcre2_get_startchar(match_data);
(void)pcre2_get_error_message(*mrc, mbuffer, sizeof(mbuffer));
fprintf(stderr, "%s at offset %" SIZ_FORM "\n\n", mbuffer,
SIZ_CAST startchar);
fprintf(stderr, "%s at offset %" SIZ_FORM "\n\n", mbuffer, startchar);
}
if (*mrc == PCRE2_ERROR_MATCHLIMIT || *mrc == PCRE2_ERROR_DEPTHLIMIT ||
*mrc == PCRE2_ERROR_HEAPLIMIT || *mrc == PCRE2_ERROR_JIT_STACKLIMIT)

View File

@ -169,19 +169,21 @@ commented out the original, but kept it around just in case. */
/* void vms_setsymbol( char *, char *, int ); Original code from [1]. */
#endif
/* VC and older compilers don't support %td or %zu, and even some that claim to
be C99 don't support it (hence DISABLE_PERCENT_ZT). There are some non-C99
environments where %lu gives a warning with 32-bit pointers. As there doesn't
seem to be an easy way round this, just live with it (the cases are rare). */
/* old VC and older compilers don't support %td or %zu, and even some that
claim to be C99 don't support it (hence DISABLE_PERCENT_ZT). */
#if defined(_MSC_VER) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || defined(DISABLE_PERCENT_ZT)
#define PTR_FORM "lu"
#if defined(DISABLE_PERCENT_ZT) || (defined(_MSC_VER) && (_MSC_VER < 1800)) || \
(!defined(_MSC_VER) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)))
#ifdef _WIN64
#define PTR_FORM "lld"
#define SIZ_FORM "llu"
#else
#define PTR_FORM "ld"
#define SIZ_FORM "lu"
#define SIZ_CAST (unsigned long int)
#endif
#else
#define PTR_FORM "td"
#define SIZ_FORM "zu"
#define SIZ_CAST
#endif
/* ------------------End of system-specific definitions -------------------- */
@ -2746,11 +2748,11 @@ if (show_memory)
{
if (block == NULL)
{
fprintf(outfile, "** malloc() failed for %" SIZ_FORM "\n", SIZ_CAST size);
fprintf(outfile, "** malloc() failed for %" SIZ_FORM "\n", size);
}
else
{
fprintf(outfile, "malloc %5" SIZ_FORM, SIZ_CAST size);
fprintf(outfile, "malloc %5" SIZ_FORM, size);
#ifdef DEBUG_SHOW_MALLOC_ADDRESSES
fprintf(outfile, " %p", block); /* Not portable */
#endif
@ -2780,7 +2782,7 @@ if (show_memory)
{
if (block == malloclist[i])
{
fprintf(outfile, " %5" SIZ_FORM, SIZ_CAST malloclistlength[i]);
fprintf(outfile, " %5" SIZ_FORM, malloclistlength[i]);
malloclistptr--;
for (j = i; j < malloclistptr; j++)
{
@ -3160,7 +3162,7 @@ if (pbuffer16_size < 2*len + 2)
if (pbuffer16 == NULL)
{
fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer16\n",
SIZ_CAST pbuffer16_size);
pbuffer16_size);
exit(1);
}
}
@ -3247,7 +3249,7 @@ if (pbuffer32_size < 4*len + 4)
if (pbuffer32 == NULL)
{
fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer32\n",
SIZ_CAST pbuffer32_size);
pbuffer32_size);
exit(1);
}
}
@ -5032,7 +5034,7 @@ switch(cmd)
if (serial == NULL)
{
fprintf(outfile, "** Failed to get memory (size %" SIZ_FORM ") for #load\n",
SIZ_CAST serial_size);
serial_size);
fclose(f);
return PR_ABEND;
}
@ -5707,7 +5709,7 @@ if (pat_patctl.convert_type != CONVERT_UNSET)
if (rc != 0)
{
fprintf(outfile, "** Pattern conversion error at offset %" SIZ_FORM ": ",
SIZ_CAST converted_length);
converted_length);
convert_return = print_error_message(rc, "", "\n")? PR_SKIP:PR_ABEND;
}
@ -6108,13 +6110,13 @@ BOOL utf = (FLD(compiled_code, overall_options) & PCRE2_UTF) != 0;
fprintf(outfile, "%2d(%d) Old %" SIZ_FORM " %" SIZ_FORM " \"",
scb->subscount, scb->oveccount,
SIZ_CAST scb->ovector[0], SIZ_CAST scb->ovector[1]);
scb->ovector[0], scb->ovector[1]);
PCHARSV(scb->input, scb->ovector[0], scb->ovector[1] - scb->ovector[0],
utf, outfile);
fprintf(outfile, "\" New %" SIZ_FORM " %" SIZ_FORM " \"",
SIZ_CAST scb->output_offsets[0], SIZ_CAST scb->output_offsets[1]);
scb->output_offsets[0], scb->output_offsets[1]);
PCHARSV(scb->output, scb->output_offsets[0],
scb->output_offsets[1] - scb->output_offsets[0], utf, outfile);
@ -6201,7 +6203,7 @@ if (cb->callout_string != NULL)
{
uint32_t delimiter = CODE_UNIT(cb->callout_string, -1);
fprintf(outfile, "Callout (%" SIZ_FORM "): %c",
SIZ_CAST cb->callout_string_offset, delimiter);
cb->callout_string_offset, delimiter);
PCHARSV(cb->callout_string, 0,
cb->callout_string_length, utf, outfile);
for (i = 0; callout_start_delims[i] != 0; i++)
@ -6401,11 +6403,11 @@ for (i = 0; i < MAXCPYGET && dat_datctl.copy_numbers[i] >= 0; i++)
else if (length2 != length)
{
fprintf(outfile, "Mismatched substring lengths: %"
SIZ_FORM " %" SIZ_FORM "\n", SIZ_CAST length, SIZ_CAST length2);
SIZ_FORM " %" SIZ_FORM "\n", length, length2);
}
fprintf(outfile, "%2dC ", n);
PCHARSV(copybuffer, 0, length, utf, outfile);
fprintf(outfile, " (%" SIZ_FORM ")\n", SIZ_CAST length);
fprintf(outfile, " (%" SIZ_FORM ")\n", length);
}
}
@ -6456,11 +6458,11 @@ for (;;)
else if (length2 != length)
{
fprintf(outfile, "Mismatched substring lengths: %"
SIZ_FORM " %" SIZ_FORM "\n", SIZ_CAST length, SIZ_CAST length2);
SIZ_FORM " %" SIZ_FORM "\n", length, length2);
}
fprintf(outfile, " C ");
PCHARSV(copybuffer, 0, length, utf, outfile);
fprintf(outfile, " (%" SIZ_FORM ") %s", SIZ_CAST length, nptr);
fprintf(outfile, " (%" SIZ_FORM ") %s", length, nptr);
if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber);
else fprintf(outfile, " (non-unique)\n");
}
@ -6485,7 +6487,7 @@ for (i = 0; i < MAXCPYGET && dat_datctl.get_numbers[i] >= 0; i++)
{
fprintf(outfile, "%2dG ", n);
PCHARSV(gotbuffer, 0, length, utf, outfile);
fprintf(outfile, " (%" SIZ_FORM ")\n", SIZ_CAST length);
fprintf(outfile, " (%" SIZ_FORM ")\n", length);
PCRE2_SUBSTRING_FREE(gotbuffer);
}
}
@ -6529,7 +6531,7 @@ for (;;)
{
fprintf(outfile, " G ");
PCHARSV(gotbuffer, 0, length, utf, outfile);
fprintf(outfile, " (%" SIZ_FORM ") %s", SIZ_CAST length, nptr);
fprintf(outfile, " (%" SIZ_FORM ") %s", length, nptr);
if (groupnumber >= 0) fprintf(outfile, " (group %d)\n", groupnumber);
else fprintf(outfile, " (non-unique)\n");
PCRE2_SUBSTRING_FREE(gotbuffer);
@ -7365,7 +7367,7 @@ if (dat_datctl.replacement[0] != 0)
if (n > nsize)
{
fprintf(outfile, "Replacement buffer setting (%" SIZ_FORM ") is too "
"large (max %" SIZ_FORM ")\n", SIZ_CAST n, SIZ_CAST nsize);
"large (max %" SIZ_FORM ")\n", n, nsize);
return PR_OK;
}
nsize = n;
@ -7997,7 +7999,7 @@ for (gmatched = 0;; gmatched++)
{
PCRE2_SIZE startchar;
PCRE2_GET_STARTCHAR(startchar, match_data);
fprintf(outfile, " at offset %" SIZ_FORM, SIZ_CAST startchar);
fprintf(outfile, " at offset %" SIZ_FORM, startchar);
}
fprintf(outfile, "\n");
break;
@ -8853,7 +8855,7 @@ least 128 code units, because it is used for retrieving error messages. */
if (pbuffer16 == NULL)
{
fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer16\n",
SIZ_CAST pbuffer16_size);
pbuffer16_size);
yield = 1;
goto EXIT;
}
@ -8868,7 +8870,7 @@ least 128 code units, because it is used for retrieving error messages. */
if (pbuffer32 == NULL)
{
fprintf(stderr, "pcre2test: malloc(%" SIZ_FORM ") failed for pbuffer32\n",
SIZ_CAST pbuffer32_size);
pbuffer32_size);
yield = 1;
goto EXIT;
}