Changeset 18182 in webkit


Ignore:
Timestamp:
Dec 12, 2006 12:09:58 PM (17 years ago)
Author:
ap
Message:

Reviewed by Geoff. Based on a patch by Maks Orlovich.

http://bugs.webkit.org/show_bug.cgi?id=6257
Throw errors on invalid expressions (KJS merge)

JavaScriptCore:

  • kjs/regexp.cpp: (KJS::RegExp::RegExp): (KJS::RegExp::~RegExp): (KJS::RegExp::match):
  • kjs/regexp.h: (KJS::RegExp::flags): (KJS::RegExp::isValid): (KJS::RegExp::errorMessage): (KJS::RegExp::subPatterns): Remember and report RegExp construction failures. Renamed data members not to start with underscores.
  • kjs/regexp_object.cpp: (RegExpObjectImp::construct): Raise an exception if RegExp construction fails. (RegExpObjectImp::callAsFunction): Removed an obsolete comment.
  • tests/mozilla/ecma_3/RegExp/regress-119909.js: Reduced the number of nested parentheses to a value supported by PCRE.

LayoutTests:

  • fast/js/kde/RegExp-expected.txt: One more test passes.
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r18170 r18182  
     12006-12-12  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Geoff. Based on a patch by Maks Orlovich.
     4
     5        http://bugs.webkit.org/show_bug.cgi?id=6257
     6        Throw errors on invalid expressions (KJS merge)
     7
     8        * kjs/regexp.cpp:
     9        (KJS::RegExp::RegExp):
     10        (KJS::RegExp::~RegExp):
     11        (KJS::RegExp::match):
     12        * kjs/regexp.h:
     13        (KJS::RegExp::flags):
     14        (KJS::RegExp::isValid):
     15        (KJS::RegExp::errorMessage):
     16        (KJS::RegExp::subPatterns):
     17        Remember and report RegExp construction failures. Renamed data members not to start with underscores.
     18
     19        * kjs/regexp_object.cpp:
     20        (RegExpObjectImp::construct): Raise an exception if RegExp construction fails.
     21        (RegExpObjectImp::callAsFunction): Removed an obsolete comment.
     22
     23        * tests/mozilla/ecma_3/RegExp/regress-119909.js: Reduced the number of nested parentheses to
     24        a value supported by PCRE.
     25
    1262006-12-11  Alexey Proskuryakov  <ap@webkit.org>
    227
  • trunk/JavaScriptCore/kjs/regexp.cpp

    r17862 r18182  
    22/*
    33 *  This file is part of the KDE libraries
    4  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
     4 *  Copyright (C) 1999-2001,2004 Harri Porten (porten@kde.org)
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    2323#include "regexp.h"
    2424
     25#include "lexer.h"
     26
    2527#include <assert.h>
    2628#include <stdio.h>
     
    3133
    3234RegExp::RegExp(const UString &p, int flags)
    33   : _flags(flags), _numSubPatterns(0)
     35  : m_flags(flags), m_constructionError(0), m_numSubPatterns(0)
    3436{
    3537#if HAVE(PCREPOSIX)
     
    4951 
    5052  pattern.append('\0');
    51   _regex = pcre_compile(reinterpret_cast<const uint16_t*>(pattern.data()),
     53  m_regex = pcre_compile(reinterpret_cast<const uint16_t*>(pattern.data()),
    5254                        options, &errorMessage, &errorOffset, NULL);
    53   if (!_regex) {
     55  if (!m_regex) {
    5456    // Try again, this time handle any \u we might find.
    5557    UString uPattern = sanitizePattern(pattern);
    56     _regex = pcre_compile(reinterpret_cast<const uint16_t*>(uPattern.data()),
     58    m_regex = pcre_compile(reinterpret_cast<const uint16_t*>(uPattern.data()),
    5759                          options, &errorMessage, &errorOffset, NULL);
    58     if (!_regex)
     60    if (!m_regex) {
     61      m_constructionError = strdup(errorMessage);
    5962      return;
     63    }
    6064  }
    6165
    6266#ifdef PCRE_INFO_CAPTURECOUNT
    6367  // Get number of subpatterns that will be returned.
    64   pcre_fullinfo(_regex, NULL, PCRE_INFO_CAPTURECOUNT, &_numSubPatterns);
     68  pcre_fullinfo(m_regex, NULL, PCRE_INFO_CAPTURECOUNT, &m_numSubPatterns);
    6569#endif
    6670
     
    8185  // Note: the Global flag is already handled by RegExpProtoFunc::execute
    8286
    83   regcomp(&_regex, p.ascii(), regflags);
    84   /* TODO check for errors */
     87  // FIXME: support \u Unicode escapes.
     88
     89  int errorCode = regcomp(&m_regex, intern.ascii(), regflags);
     90  if (errorCode != 0) {
     91    char errorMessage[80];
     92    regerror(errorCode, &m_regex, errorMessage, sizeof errorMessage);
     93    m_constructionError = strdup(errorMessage);
     94  }
    8595
    8696#endif
     
    90100{
    91101#if HAVE(PCREPOSIX)
    92   pcre_free(_regex);
     102  pcre_free(m_regex);
    93103#else
    94104  /* TODO: is this really okay after an error ? */
    95   regfree(&_regex);
    96 #endif
     105  regfree(&m_regex);
     106#endif
     107  free(m_constructionError);
    97108}
    98109
     
    113124#if HAVE(PCREPOSIX)
    114125
    115   if (!_regex)
     126  if (!m_regex)
    116127    return UString::null();
    117128
     
    125136    offsetVector = fixedSizeOffsetVector;
    126137  } else {
    127     offsetVectorSize = (_numSubPatterns + 1) * 3;
     138    offsetVectorSize = (m_numSubPatterns + 1) * 3;
    128139    offsetVector = new int [offsetVectorSize];
    129140  }
    130141
    131   const int numMatches = pcre_exec(_regex, NULL, reinterpret_cast<const uint16_t *>(s.data()), s.size(), i, 0, offsetVector, offsetVectorSize);
     142  const int numMatches = pcre_exec(m_regex, NULL, reinterpret_cast<const uint16_t *>(s.data()), s.size(), i, 0, offsetVector, offsetVectorSize);
    132143
    133144  if (numMatches < 0) {
     
    152163
    153164  char *str = strdup(s.ascii()); // TODO: why ???
    154   if (regexec(&_regex, str + i, maxMatch, rmatch, 0)) {
     165  if (regexec(&m_regex, str + i, maxMatch, rmatch, 0)) {
    155166    free(str);
    156167    return UString::null();
     
    164175
    165176  // map rmatch array to ovector used in PCRE case
    166   _numSubPatterns = 0;
     177  m_numSubPatterns = 0;
    167178  for(unsigned j = 1; j < maxMatch && rmatch[j].rm_so >= 0 ; j++)
    168       _numSubPatterns++;
    169   int ovecsize = (_numSubPatterns+1)*3; // see above
     179      m_numSubPatterns++;
     180  int ovecsize = (m_numSubPatterns+1)*3; // see above
    170181  *ovector = new int[ovecsize];
    171   for (unsigned j = 0; j < _numSubPatterns + 1; j++) {
     182  for (unsigned j = 0; j < m_numSubPatterns + 1; j++) {
    172183    if (j>maxMatch)
    173184      break;
  • trunk/JavaScriptCore/kjs/regexp.h

    r17862 r18182  
    4646    ~RegExp();
    4747
    48     int flags() const { return _flags; }
     48    int flags() const { return m_flags; }
     49    bool isValid() const { return !m_constructionError; }
     50    const char* errorMessage() const { return m_constructionError; }
    4951
    5052    UString match(const UString &s, int i, int *pos = 0, int **ovector = 0);
    51     unsigned subPatterns() const { return _numSubPatterns; }
     53    unsigned subPatterns() const { return m_numSubPatterns; }
    5254
    5355  private:
    5456#if HAVE(PCREPOSIX)
    55     pcre *_regex;
     57    pcre *m_regex;
    5658#else
    57     regex_t _regex;
     59    regex_t m_regex;
    5860#endif
    59     int _flags;
    60     unsigned _numSubPatterns;
     61    int m_flags;
     62    char* m_constructionError;
     63    unsigned m_numSubPatterns;
    6164
    6265    RegExp(const RegExp &);
  • trunk/JavaScriptCore/kjs/regexp_object.cpp

    r15846 r18182  
    383383  bool ignoreCase = (flags.find("i") >= 0);
    384384  bool multiline = (flags.find("m") >= 0);
    385   // TODO: throw a syntax error on invalid flags
    386385
    387386  dat->putDirect("global", jsBoolean(global), DontDelete | ReadOnly | DontEnum);
     
    399398  if (multiline)
    400399      reflags |= RegExp::Multiline;
    401   dat->setRegExp(new RegExp(p, reflags));
     400  RegExp* re = new RegExp(p, reflags);
     401  if (!re->isValid()) {
     402    delete re;
     403    return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(re->errorMessage()));
     404  }
     405  dat->setRegExp(re);
    402406
    403407  return dat;
     
    407411JSValue *RegExpObjectImp::callAsFunction(ExecState *exec, JSObject * /*thisObj*/, const List &args)
    408412{
    409   // TODO: handle RegExp argument case (15.10.3.1)
    410 
    411413  return construct(exec, args);
    412414}
  • trunk/JavaScriptCore/tests/mozilla/ecma_3/RegExp/regress-119909.js

    r11995 r18182  
    5858  printStatus(summary);
    5959
    60   testThis(500, NO_BACKREFS, 'hello', 'goodbye');
    61   testThis(500, DO_BACKREFS, 'hello', 'goodbye');
     60  // Changed the parameter from 500 to 200 for WebKit, because PCRE reports an error for more parentheses.
     61  testThis(200, NO_BACKREFS, 'hello', 'goodbye');
     62  testThis(200, DO_BACKREFS, 'hello', 'goodbye');
    6263
    6364  exitFunc('test');
  • trunk/LayoutTests/ChangeLog

    r18177 r18182  
     12006-12-12  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Geoff.
     4
     5        http://bugs.webkit.org/show_bug.cgi?id=6257
     6        Throw errors on invalid expressions (KJS merge)
     7
     8        * fast/js/kde/RegExp-expected.txt: One more test passes.
     9
    1102006-12-12  Nikolas Zimmermann  <zimmermann@kde.org>
    211
  • trunk/LayoutTests/fast/js/kde/RegExp-expected.txt

    r17862 r18182  
    6363PASS 'test1test2'.replace(/(te)(st)/g,'$2$1') is 'stte1stte2'
    6464PASS 'foo+bar'.replace(/\+/g,'%2B') is 'foo%2Bbar'
    65 FAIL caught should be true (of type boolean). Was false (of type boolean).
     65PASS caught is true
    6666PASS 'foo'.replace(/z?/g,'x') is 'xfxoxox'
    6767PASS 'test test'.replace(/\s*/g,'') is 'testtest'
Note: See TracChangeset for help on using the changeset viewer.