[pcre-dev] [Bug 2173] New: stack frame size detection is bro…

Top Page
Delete this message
Author: admin
Date:  
To: pcre-dev
New-Topics: [pcre-dev] [Bug 2173] stack frame size detection is broken
Subject: [pcre-dev] [Bug 2173] New: stack frame size detection is broken
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: ph10@???
          Reporter: vuvova@???
                CC: pcre-dev@???


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.