bugGNU Octave - Bugs: bug #62704, Regexpi() fatal error triggers...

 
 

bug #62704: Regexpi() fatal error triggers core dump

Submitter:  None
Submitted:  Mon 04 Jul 2022 12:22:11 PM UTC
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * 7.1.90
Operating System:  * Any
* Mandatory Fields

Add a New Comment (Rich Markup)
   

Comment Type & Canned Response:
       

 

( Jump to the original submission )

Tue 05 Jul 2022 06:25:26 AM UTC, comment #9: 

Oops. Didn't notice the double quotes in your example. So, your second example is actually the same as the first example (and should fail with the same error).
Your last example also correctly matches nothing.

Markus Mützel <mmuetzel>
Project Member
Tue 05 Jul 2022 04:02:41 AM UTC, comment #8: 

Thanks for testing.

I opened bug #62705 for the patterns that are incorrectly categorized.
IIUC, your first pattern is invalid. So, an error for that is probably ok. Your seconds pattern should work (and not match anything). The third example is invalid and should probably produce an error.

If you like, you could add those examples to the other report.
Categorizing those types of patterns correctly is not trivial. I don't plan on working on that currently.

Closing this as fixed because Octave no longer crashes.

Markus Mützel <mmuetzel>
Project Member
Mon 04 Jul 2022 09:34:36 PM UTC, comment #7: 

It does not crash, so that part is fixed.

I now get the following behavior for Octave 8. Is this intended?

octave:1> regexpi ("foo", "(?")
error: regexpi: unrecognized character after (? or (?- at position 2 of expression
octave:2> regexpi ("foo", "\(?")
error: regexpi: unrecognized character after (? or (?- at position 2 of expression
octave:3> regexpi ("foo", "\\(?")
ans = [](1x0)

Arun Giridhar <arungiridhar>
Project Member
Mon 04 Jul 2022 07:40:28 PM UTC, comment #6: 

I pushed a patch that should be fixing this to the stable branch here:
https://hg.savannah.gnu.org/hgweb/octave/rev/5cf18ef0377c

Marking as ready for test.

Markus Mützel <mmuetzel>
Project Member
Mon 04 Jul 2022 04:47:56 PM UTC, comment #5: 

@mmuetzel: crossed with your comment by a few minutes. Yes, we're in agreement on the cause and location. I'll wait for your fix.

Arun Giridhar <arungiridhar>
Project Member
Mon 04 Jul 2022 04:45:57 PM UTC, comment #4: 

Localized the error.

By adding

std::cerr << __LINE__ << '\n';

through the regexpi functions, the crash could be localized to this statement in the octregexp function in regexp.cc:

  const regexp::match_data rx_lst
    = regexp::match (pattern, buffer, options, who);

That statement in turn calls this function in lo-regexp.h:

    static match_data
    match (const std::string& pat, const std::string& buffer,
           const regexp::opts& opt = regexp::opts (),
           const std::string& who = "regexp")
    {
      regexp rx (pat, opt, who);

      return rx.match (buffer);
    }

The first line triggers the error:

      regexp rx (pat, opt, who);

That constructor is just a wrapper to compile_internal():

    regexp (const std::string& pat = "",
            const regexp::opts& opt = regexp::opts (),
            const std::string& w = "regexp")
      : m_pattern (pat), m_options (opt), m_data (nullptr), m_named_pats (),
        m_names (0), m_named_idx (), m_who (w)
    {
      compile_internal ();
    }

The buffer overflow happens in compile_internal() in lo-regexp.cc in this sequence:

    85            std::cerr << __LINE__ << '\n';
    86
    87            while ((new_pos = m_pattern.find ("(?", pos)) != std::string::npos)
    88              {
    89                std::cerr << __LINE__ << '\n';
    90                if (m_pattern.at (new_pos + 2) == '<'
    91                    && !(m_pattern.at (new_pos + 3) == '='
    92                         || m_pattern.at (new_pos + 3) == '!'))
    93                  {
    94                    // The syntax of named tokens in pcre is "(?P<name>...)" while
    95                    // we need a syntax "(?<name>...)", so fix that here.  Also an
    96                    // expression like
    97                    // "(?<first>\w+)\s+(?<last>\w+)|(?<last>\w+),\s+(?<first>\w+)"
    98                    // should be perfectly legal, while pcre does not allow the same
    99                    // named token name on both sides of the alternative.  Also fix
   100                    // that here by replacing name tokens by dummy names, and dealing
   101                    // with the dummy names later.
   102
   103                    std::cerr << __LINE__ << '\n';

The cerr calls at line 85 and line 89 both work, then the if-statement at line 90 causes an overflow and the next cerr at line 103 is not called.

Does there need to be a length guard before we call m_pattern.at()?

Arun Giridhar <arungiridhar>
Project Member
Mon 04 Jul 2022 04:42:07 PM UTC, comment #3: 

It looks like it is trying to detect a look-around pattern (like patterns starting with "(?<=") and exceeds the end of the string.

I think I know how to fix that.

Markus Mützel <mmuetzel>
Project Member
Mon 04 Jul 2022 12:37:04 PM UTC, comment #2: 

Changing version and status per @dasergatskov's confirmation. Changing to crash per OP's error message.

Arun Giridhar <arungiridhar>
Project Member
Mon 04 Jul 2022 12:32:44 PM UTC, comment #1: 

I can confirm on 7060de0b45e5 (stable) (pre 7.2) on linux.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 04 Jul 2022 12:22:11 PM UTC, original submission:  

Hi,
we noticed that a certain pattern string in regexpi() leads to Octave stopping and closing itself. When started via terminal (i.e. not as GUI), the last output is

terminate called after throwing an instance of ‘std::out_of_range’
what(): basic_string::at: __n (which is 3) >= this->size() (which is 3)
fatal: caught signal Aborted – stopping myself…
Aborted (core dumped)

The faulty expression is regexpi('(','\(?'). A possible workaround is adding parentheses like regexpi('(','(\()?'), but we aren’t quite sure why - is '\(?' (=search for an optional opening parenthesis) not a valid pattern?

Happens on both Win10 + Octave 6.3 & 7.1, and Ubuntu 20.04 + Octave 6.3

Thanks in advance!

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by arungiridhar (Posted a comment)
  • -email is unavailable- added by dasergatskov (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only project members can vote.

     

     

     

     

    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-07-05 mmuetzel StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2022-07-04 mmuetzel StatusConfirmed Ready For Test
    2022-07-04 arungiridhar Item GroupUnexpected Error or Warning Segfault, Bus Error, etc.
        StatusNone Confirmed
        Release6.3.0 7.1.90

    Back to the top


    Powered by Savane 3.9