Make bcopy() emulation of memmove() work properly.
This commit is contained in:
parent
9332d4be69
commit
1a8cc3dab6
|
@ -148,6 +148,13 @@ end of its group during the parse process, but without another setting such as
|
||||||
(?m) the compile phase got it right.) This bug was introduced by the
|
(?m) the compile phase got it right.) This bug was introduced by the
|
||||||
refactoring in release 10.23.
|
refactoring in release 10.23.
|
||||||
|
|
||||||
|
33. PCRE2 uses bcopy() if available when memmove() is not, and it used just to
|
||||||
|
define memmove() as function call to bcopy(). This hasn't been tested for a
|
||||||
|
long time because in pcre2test the result of memmove() was being used, whereas
|
||||||
|
bcopy() doesn't return a result. This feature is now refactored always to call
|
||||||
|
an emulation function when there is no memmove(). The emulation makes use of
|
||||||
|
bcopy() when available.
|
||||||
|
|
||||||
|
|
||||||
Version 10.31 12-February-2018
|
Version 10.31 12-February-2018
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
|
@ -5655,7 +5655,7 @@ for (;; pptr++)
|
||||||
if (class_has_8bitchar > 0)
|
if (class_has_8bitchar > 0)
|
||||||
{
|
{
|
||||||
*code++ |= XCL_MAP;
|
*code++ |= XCL_MAP;
|
||||||
memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,
|
(void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code,
|
||||||
CU2BYTES(class_uchardata - code));
|
CU2BYTES(class_uchardata - code));
|
||||||
if (negate_class && !xclass_has_prop)
|
if (negate_class && !xclass_has_prop)
|
||||||
for (i = 0; i < 32; i++) classbits[i] = ~classbits[i];
|
for (i = 0; i < 32; i++) classbits[i] = ~classbits[i];
|
||||||
|
@ -6602,7 +6602,7 @@ for (;; pptr++)
|
||||||
|
|
||||||
/* Wrap the recursion call in OP_BRA brackets. */
|
/* Wrap the recursion call in OP_BRA brackets. */
|
||||||
|
|
||||||
memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
|
(void)memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
|
||||||
op_previous = *previous = OP_BRA;
|
op_previous = *previous = OP_BRA;
|
||||||
PUT(previous, 1, 2 + 2*LINK_SIZE);
|
PUT(previous, 1, 2 + 2*LINK_SIZE);
|
||||||
previous[2 + 2*LINK_SIZE] = OP_KET;
|
previous[2 + 2*LINK_SIZE] = OP_KET;
|
||||||
|
@ -6682,7 +6682,7 @@ for (;; pptr++)
|
||||||
|
|
||||||
if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED)
|
if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED)
|
||||||
{
|
{
|
||||||
memmove(previous + 1, previous, CU2BYTES(len));
|
(void)memmove(previous + 1, previous, CU2BYTES(len));
|
||||||
code++;
|
code++;
|
||||||
if (repeat_max == 0)
|
if (repeat_max == 0)
|
||||||
{
|
{
|
||||||
|
@ -6703,7 +6703,7 @@ for (;; pptr++)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int linkoffset;
|
int linkoffset;
|
||||||
memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));
|
(void)memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len));
|
||||||
code += 2 + LINK_SIZE;
|
code += 2 + LINK_SIZE;
|
||||||
*previous++ = OP_BRAZERO + repeat_type;
|
*previous++ = OP_BRAZERO + repeat_type;
|
||||||
*previous++ = OP_BRA;
|
*previous++ = OP_BRA;
|
||||||
|
@ -6904,7 +6904,7 @@ for (;; pptr++)
|
||||||
if (*bracode == OP_COND || *bracode == OP_SCOND)
|
if (*bracode == OP_COND || *bracode == OP_SCOND)
|
||||||
{
|
{
|
||||||
int nlen = (int)(code - bracode);
|
int nlen = (int)(code - bracode);
|
||||||
memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
|
(void)memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
|
||||||
code += 1 + LINK_SIZE;
|
code += 1 + LINK_SIZE;
|
||||||
nlen += 1 + LINK_SIZE;
|
nlen += 1 + LINK_SIZE;
|
||||||
*bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
|
*bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
|
||||||
|
@ -7175,7 +7175,7 @@ for (;; pptr++)
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));
|
(void)memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len));
|
||||||
code += 1 + LINK_SIZE;
|
code += 1 + LINK_SIZE;
|
||||||
len += 1 + LINK_SIZE;
|
len += 1 + LINK_SIZE;
|
||||||
tempcode[0] = OP_ONCE;
|
tempcode[0] = OP_ONCE;
|
||||||
|
@ -7715,7 +7715,7 @@ for (;;)
|
||||||
{
|
{
|
||||||
if (cb->open_caps->flag)
|
if (cb->open_caps->flag)
|
||||||
{
|
{
|
||||||
memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
|
(void)memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
|
||||||
CU2BYTES(code - start_bracket));
|
CU2BYTES(code - start_bracket));
|
||||||
*start_bracket = OP_ONCE;
|
*start_bracket = OP_ONCE;
|
||||||
code += 1 + LINK_SIZE;
|
code += 1 + LINK_SIZE;
|
||||||
|
@ -8315,7 +8315,7 @@ for (i = 0; i < tablecount; i++)
|
||||||
|
|
||||||
if (crc < 0)
|
if (crc < 0)
|
||||||
{
|
{
|
||||||
memmove(slot + cb->name_entry_size, slot,
|
(void)memmove(slot + cb->name_entry_size, slot,
|
||||||
CU2BYTES((tablecount - i) * cb->name_entry_size));
|
CU2BYTES((tablecount - i) * cb->name_entry_size));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -875,7 +875,7 @@ for (;;)
|
||||||
else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)
|
else if (match_count > 0 && ++match_count * 2 > (int)offsetcount)
|
||||||
match_count = 0;
|
match_count = 0;
|
||||||
count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;
|
count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2;
|
||||||
if (count > 0) memmove(offsets + 2, offsets,
|
if (count > 0) (void)memmove(offsets + 2, offsets,
|
||||||
(size_t)count * sizeof(PCRE2_SIZE));
|
(size_t)count * sizeof(PCRE2_SIZE));
|
||||||
if (offsetcount >= 2)
|
if (offsetcount >= 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -165,6 +165,16 @@ by "configure". */
|
||||||
#define INT64_OR_DOUBLE double
|
#define INT64_OR_DOUBLE double
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* External (in the C sense) functions and tables that are private to the
|
||||||
|
libraries are always referenced using the PRIV macro. This makes it possible
|
||||||
|
for pcre2test.c to include some of the source files from the libraries using a
|
||||||
|
different PRIV definition to avoid name clashes. It also makes it clear in the
|
||||||
|
code that a non-static object is being referenced. */
|
||||||
|
|
||||||
|
#ifndef PRIV
|
||||||
|
#define PRIV(name) _pcre2_##name
|
||||||
|
#endif
|
||||||
|
|
||||||
/* When compiling for use with the Virtual Pascal compiler, these functions
|
/* When compiling for use with the Virtual Pascal compiler, these functions
|
||||||
need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT
|
need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT
|
||||||
option on the command line. */
|
option on the command line. */
|
||||||
|
@ -178,50 +188,15 @@ option on the command line. */
|
||||||
#define memset(s,c,n) _memset(s,c,n)
|
#define memset(s,c,n) _memset(s,c,n)
|
||||||
#else /* VPCOMPAT */
|
#else /* VPCOMPAT */
|
||||||
|
|
||||||
/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
|
/* Otherwise, to cope with SunOS4 and other systems that lack memmove(), define
|
||||||
define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
|
a macro that calls an emulating function. */
|
||||||
is set. Otherwise, include an emulating function for those systems that have
|
|
||||||
neither (there some non-Unix environments where this is the case). */
|
|
||||||
|
|
||||||
#ifndef HAVE_MEMMOVE
|
#ifndef HAVE_MEMMOVE
|
||||||
#undef memmove /* some systems may have a macro */
|
#undef memmove /* Some systems may have a macro */
|
||||||
#ifdef HAVE_BCOPY
|
#define memmove(a, b, c) PRIV(memmove)(a, b, c)
|
||||||
#define memmove(a, b, c) bcopy(b, a, c)
|
|
||||||
#else /* HAVE_BCOPY */
|
|
||||||
static void *
|
|
||||||
pcre2_memmove(void *d, const void *s, size_t n)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
unsigned char *dest = (unsigned char *)d;
|
|
||||||
const unsigned char *src = (const unsigned char *)s;
|
|
||||||
if (dest > src)
|
|
||||||
{
|
|
||||||
dest += n;
|
|
||||||
src += n;
|
|
||||||
for (i = 0; i < n; ++i) *(--dest) = *(--src);
|
|
||||||
return (void *)dest;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < n; ++i) *dest++ = *src++;
|
|
||||||
return (void *)(dest - n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#define memmove(a, b, c) pcre2_memmove(a, b, c)
|
|
||||||
#endif /* not HAVE_BCOPY */
|
|
||||||
#endif /* not HAVE_MEMMOVE */
|
#endif /* not HAVE_MEMMOVE */
|
||||||
#endif /* not VPCOMPAT */
|
#endif /* not VPCOMPAT */
|
||||||
|
|
||||||
/* External (in the C sense) functions and tables that are private to the
|
|
||||||
libraries are always referenced using the PRIV macro. This makes it possible
|
|
||||||
for pcre2test.c to include some of the source files from the libraries using a
|
|
||||||
different PRIV definition to avoid name clashes. It also makes it clear in the
|
|
||||||
code that a non-static object is being referenced. */
|
|
||||||
|
|
||||||
#ifndef PRIV
|
|
||||||
#define PRIV(name) _pcre2_##name
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is an unsigned int value that no UTF character can ever have, as
|
/* This is an unsigned int value that no UTF character can ever have, as
|
||||||
Unicode doesn't go beyond 0x0010ffff. */
|
Unicode doesn't go beyond 0x0010ffff. */
|
||||||
|
|
||||||
|
@ -1985,6 +1960,14 @@ extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *);
|
||||||
extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
|
extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR,
|
||||||
uint32_t *, BOOL);
|
uint32_t *, BOOL);
|
||||||
extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL);
|
extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL);
|
||||||
|
|
||||||
|
/* This function is needed only when memmove() is not available. */
|
||||||
|
|
||||||
|
#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
|
||||||
|
#define _pcre2_memmove PCRE2_SUFFIX(_pcre2_memmove)
|
||||||
|
extern void * _pcre2_memmove(void *, const void *, size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* PCRE2_CODE_UNIT_WIDTH */
|
#endif /* PCRE2_CODE_UNIT_WIDTH */
|
||||||
#endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */
|
#endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||||
|
|
||||||
Written by Philip Hazel
|
Written by Philip Hazel
|
||||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||||
New API code Copyright (c) 2016 University of Cambridge
|
New API code Copyright (c) 2018 University of Cambridge
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -50,6 +50,42 @@ functions work only on 8-bit data. */
|
||||||
#include "pcre2_internal.h"
|
#include "pcre2_internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Emulated memmove() for systems without it *
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/* This function can make use of bcopy() if it is available. Otherwise do it by
|
||||||
|
steam, as there some non-Unix environments that lack both memmove() and
|
||||||
|
bcopy(). */
|
||||||
|
|
||||||
|
#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
|
||||||
|
void *
|
||||||
|
PRIV(memmove)(void *d, const void *s, size_t n)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BCOPY
|
||||||
|
bcopy(s, d, n);
|
||||||
|
return d;
|
||||||
|
#else
|
||||||
|
size_t i;
|
||||||
|
unsigned char *dest = (unsigned char *)d;
|
||||||
|
const unsigned char *src = (const unsigned char *)s;
|
||||||
|
if (dest > src)
|
||||||
|
{
|
||||||
|
dest += n;
|
||||||
|
src += n;
|
||||||
|
for (i = 0; i < n; ++i) *(--dest) = *(--src);
|
||||||
|
return (void *)dest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < n; ++i) *dest++ = *src++;
|
||||||
|
return (void *)(dest - n);
|
||||||
|
}
|
||||||
|
#endif /* not HAVE_BCOPY */
|
||||||
|
}
|
||||||
|
#endif /* not VPCOMPAT && not HAVE_MEMMOVE */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************
|
/*************************************************
|
||||||
* Compare two zero-terminated PCRE2 strings *
|
* Compare two zero-terminated PCRE2 strings *
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
|
@ -469,6 +469,43 @@ const char utf8_table4[] = {
|
||||||
3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
|
3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
|
||||||
|
/*************************************************
|
||||||
|
* Emulated memmove() for systems without it *
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/* This function can make use of bcopy() if it is available. Otherwise do it by
|
||||||
|
steam, as there are some non-Unix environments that lack both memmove() and
|
||||||
|
bcopy(). */
|
||||||
|
|
||||||
|
static void *
|
||||||
|
emulated_memmove(void *d, const void *s, size_t n)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BCOPY
|
||||||
|
bcopy(s, d, n);
|
||||||
|
return d;
|
||||||
|
#else
|
||||||
|
size_t i;
|
||||||
|
unsigned char *dest = (unsigned char *)d;
|
||||||
|
const unsigned char *src = (const unsigned char *)s;
|
||||||
|
if (dest > src)
|
||||||
|
{
|
||||||
|
dest += n;
|
||||||
|
src += n;
|
||||||
|
for (i = 0; i < n; ++i) *(--dest) = *(--src);
|
||||||
|
return (void *)dest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < n; ++i) *dest++ = *src++;
|
||||||
|
return (void *)(dest - n);
|
||||||
|
}
|
||||||
|
#endif /* not HAVE_BCOPY */
|
||||||
|
}
|
||||||
|
#undef memmove
|
||||||
|
#define memmove(d,s,n) emulated_memmove(d,s,n)
|
||||||
|
#endif /* not VPCOMPAT && not HAVE_MEMMOVE */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************
|
/*************************************************
|
||||||
* Case-independent string compare *
|
* Case-independent string compare *
|
||||||
|
@ -2932,7 +2969,7 @@ while (ptr < endptr)
|
||||||
|
|
||||||
/* Now do the shuffle */
|
/* Now do the shuffle */
|
||||||
|
|
||||||
memmove(main_buffer, main_buffer + bufthird, 2*bufthird);
|
(void)memmove(main_buffer, main_buffer + bufthird, 2*bufthird);
|
||||||
ptr -= bufthird;
|
ptr -= bufthird;
|
||||||
|
|
||||||
bufflength = 2*bufthird + fill_buffer(handle, frtype,
|
bufflength = 2*bufthird + fill_buffer(handle, frtype,
|
||||||
|
|
|
@ -2595,6 +2595,46 @@ static const uint8_t tables2[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
|
||||||
|
/*************************************************
|
||||||
|
* Emulated memmove() for systems without it *
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
/* This function can make use of bcopy() if it is available. Otherwise do it by
|
||||||
|
steam, as there are some non-Unix environments that lack both memmove() and
|
||||||
|
bcopy(). */
|
||||||
|
|
||||||
|
static void *
|
||||||
|
emulated_memmove(void *d, const void *s, size_t n)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_BCOPY
|
||||||
|
bcopy(s, d, n);
|
||||||
|
return d;
|
||||||
|
#else
|
||||||
|
size_t i;
|
||||||
|
unsigned char *dest = (unsigned char *)d;
|
||||||
|
const unsigned char *src = (const unsigned char *)s;
|
||||||
|
if (dest > src)
|
||||||
|
{
|
||||||
|
dest += n;
|
||||||
|
src += n;
|
||||||
|
for (i = 0; i < n; ++i) *(--dest) = *(--src);
|
||||||
|
return (void *)dest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < n; ++i) *dest++ = *src++;
|
||||||
|
return (void *)(dest - n);
|
||||||
|
}
|
||||||
|
#endif /* not HAVE_BCOPY */
|
||||||
|
}
|
||||||
|
#undef memmove
|
||||||
|
#define memmove(d,s,n) emulated_memmove(d,s,n)
|
||||||
|
#endif /* not VPCOMPAT && not HAVE_MEMMOVE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_STRERROR
|
#ifndef HAVE_STRERROR
|
||||||
/*************************************************
|
/*************************************************
|
||||||
* Provide strerror() for non-ANSI libraries *
|
* Provide strerror() for non-ANSI libraries *
|
||||||
|
|
Loading…
Reference in New Issue