Hi,

I am trying to validate (using QRegularExpressionValidator) a URL. It got the regular expression from https://gist.github.com/dperini/729294 and, from what I can tell, it looks good (and it certainly seems to work when I tried using some online regular expression testers). However, my tests using Qt are anything but conclusive. So, could it be that I wrongly 'converted' the regular expression to C++?

Otherwise, worse is the fact that if I try to enter something like "http://uuuuuuuuuuuuuuuuuuuu", then my test application kind of hangs up. In fact, if I run it in debug mode and pause it, I can see that QRegularExpressionValidator::validate() makes an indirect call to pcre16_exec, which itself makes call to match, which itself makes call to match, which itself makes call to match, etc. Could this be a bug in QRegularExpressionValidator or even pcre16_exec?

QRegularExpressionValidatorTest.pro:

Qt Code:
  1. QT += core gui
  2.  
  3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  4.  
  5. TARGET = QRegularExpressionValidatorTest
  6. TEMPLATE = app
  7.  
  8. SOURCES += main.cpp
To copy to clipboard, switch view to plain text mode 

main.cpp:

Qt Code:
  1. #include <QApplication>
  2. #include <QDesktopWidget>
  3. #include <QDialog>
  4. #include <QLineEdit>
  5. #include <QRegularExpressionValidator>
  6. #include <QVBoxLayout>
  7.  
  8. int main(int pArgC, char *pArgV[])
  9. {
  10. QApplication application(pArgC, pArgV);
  11.  
  12. QDialog *dialog = new QDialog();
  13. QVBoxLayout *dialogLayout = new QVBoxLayout(dialog);
  14.  
  15. dialog->setLayout(dialogLayout);
  16. dialog->setWindowTitle("URL Tester");
  17.  
  18. // We want to validate a URL, the regular expression of which comes from
  19. // https://gist.github.com/dperini/729294
  20. // It is released under the MIT license and is therefore fine for us to use
  21.  
  22. QString urlRegExp = QString() +
  23. "^"
  24. // protocol identifier
  25. "(?:(?:https?|ftp)://)" +
  26. // user:pass authentication
  27. "(?:\\S+(?::\\S*)?@)?" +
  28. "(?:" +
  29. // IP address exclusion
  30. // private & local networks
  31. "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
  32. "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
  33. "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
  34. // IP address dotted notation octets
  35. // excludes loopback network 0.0.0.0
  36. // excludes reserved space >= 224.0.0.0
  37. // excludes network & broacast addresses
  38. // (first & last IP address of each class)
  39. "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
  40. "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
  41. "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
  42. "|" +
  43. // host name
  44. "(?:(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)" +
  45. // domain name
  46. "(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*" +
  47. // TLD identifier
  48. "(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,}))" +
  49. ")" +
  50. // port number
  51. "(?::\\d{2,5})?" +
  52. // resource path
  53. "(?:/[^\\s]*)?" +
  54. "$";
  55.  
  56. QLineEdit *dialogValue = new QLineEdit(dialog);
  57.  
  58. dialogValue->setValidator(new QRegularExpressionValidator(QRegularExpression(urlRegExp, QRegularExpression::CaseInsensitiveOption), dialog));
  59. dialogValue->setMinimumWidth(qApp->desktop()->availableGeometry().width()/5);
  60.  
  61. dialogLayout->addWidget(dialogValue);
  62.  
  63. dialogLayout->setSizeConstraint(QLayout::SetFixedSize);
  64.  
  65. dialog->show();
  66.  
  67. return application.exec();
  68. }
To copy to clipboard, switch view to plain text mode