https://bugs.exim.org/show_bug.cgi?id=2173

            Bug ID: 2173
           Summary: stack frame size detection is broken
           Product: PCRE
           Version: 8.41
          Hardware: x86
                OS: Linux
            Status: NEW
          Severity: bug
          Priority: medium
         Component: Code
          Assignee: p...@hermes.cam.ac.uk
          Reporter: vuv...@gmail.com
                CC: pcre-dev@exim.org

The documented way to check the stack frame size is

     -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0)

This doesn't work for a while, at least since gcc 5.4.0, probably earlier. The
code looks like that:
=====================================================
int
pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
  PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
  int offsetcount)
{
if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
start_offset == -999)
  return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
...
=====================================================
static int
match(PCRE_PUCHAR eptr, const pcre_uchar *ecode,
  PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
  unsigned int rdepth)
{
if (ecode == NULL)
  {
  if (rdepth == 0)
    return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
  else
    {
    int len = (int)((char *)&rdepth - (char *)eptr);
    return (len > 0)? -len : len;
    }
  }
...
=====================================================
while match() itself is rather big and complex, the code path for ecode==NULL
is simple.
Compiler clones match(), extracting that code path into a separate very small
function and inlines it directly into pcre_exec(). The result is:

$ pcretest -m -C
PCRE version 8.41 2017-07-05
Compiled with
  8-bit support
  UTF-8 support
  Unicode properties support
  Just-in-time compiler support: x86 64bit (little endian + unaligned)
  Newline sequence is LF
  \R matches all Unicode newlines
  Internal link size = 2
  POSIX malloc threshold = 10
  Parentheses nest limit = 250
  Default match limit = 10000000
  Default recursion depth limit = 8192
  Match recursion uses stack: approximate frame size = 4 bytes

As a fix, I've declared match() with __attribute__((noinline,noclone)). This
helped.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-- 
## List details at https://lists.exim.org/mailman/listinfo/pcre-dev 

Reply via email to