惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
小众软件
小众软件
Engineering at Meta
Engineering at Meta
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Google DeepMind News
Google DeepMind News
Security Archives - TechRepublic
Security Archives - TechRepublic
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Help Net Security
Martin Fowler
Martin Fowler
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
V
Vulnerabilities – Threatpost
云风的 BLOG
云风的 BLOG
博客园_首页
C
Cybersecurity and Infrastructure Security Agency CISA
量子位
Stack Overflow Blog
Stack Overflow Blog
Recent Announcements
Recent Announcements
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
Scott Helme
Scott Helme
A
About on SuperTechFans
博客园 - 司徒正美
Hacker News: Ask HN
Hacker News: Ask HN
The GitHub Blog
The GitHub Blog
Forbes - Security
Forbes - Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Spread Privacy
Spread Privacy
T
Tailwind CSS Blog
S
Security Affairs
宝玉的分享
宝玉的分享

Henri Sivonen’s pages

Parin vuoden tutkimattomuus crates.io: Rust Package Registry Asiakirjatonta toimintaa It’s not wrong that "🤦🏼‍♂️".length == 7 Koulutartuntojen tilastointimenettely Perusteasiakirjoja hallussapitämättä ikärajoitettu Asiantuntijat ja nukkuva vallan vahtikoira Koronapassilausunto Suppealla tietopohjalla ohimeneväksi väitetty Text Encoding Menu in 2021 The Text Encoding Submenu Is Gone An HTML5 Conformance Checker Not Part of the Technology Stack Browser Technology Stack Bogo-XML Declaration Returns to Gecko A Look at Encoding Detection and Encoding Menu Telemetry from Firefox 86 Why Supporting Unlabeled UTF-8 in HTML on the Web Would Be Problematic Rust Target Names Aren’t Passed to LLVM Toimintamalli Activating Browser Modes with Doctype Johtopäätöksiä mallin rakenteesta Tehtävänmäärittelyä kirjoittamatta ja kuolemia laskematta laumasuojamallinnettu Character Encoding Menu in 2014 Erillissuosituksen tarpeettomuudesta yleissuosituksen poikkeukseksi? STM:n maskiaikajana Rust 2021 Oma-aloitteisesti mallinnettu Kokopinovaatimuksin kilpailutettu chardetng: A More Compact Character Encoding Detector for the Legacy Web Varauksia paisutellen tiedotettu Perusteasiakirjoitta tiedotettu Always Use UTF-8 & Always Label Your HTML Saying So IME Smoke Testing The Validator.nu HTML Parser About the Hiragino Fonts with CSS It’s Time to Stop Adding New Features for Non-Unicode Execution Encodings in C++ Rust 2020 The Last of the Parsing Quirks About about:blank Rust 2019 a Web-Compatible Character Encoding Library in Rust How I Wrote a Modern C++ Library in Rust Using cargo-fuzz to Transfer Code Review of Simple Safe Code to Complex Code that Uses unsafe A Rust Crate that Also Quacks Like a Modern C++ Library #Rust2018 No Namespaces in JSON, Please A Lecture about HTML5 Julkisesti luotettu varmenne ikidomainille TLS:ää (SSL:ää) varten -webkit-HTML5 Lists in Attribute Values The Sad Story of PNG Gamma “Correction” If You Want Software Freedom on Phones, You Should Work on Firefox OS, Custom Hardware and Web App Self-Hostablility HTML5 Parser Improvements ARIA in HTML5 Integration: Document Conformance (Draft, Take Two) Schema.org and Pre-Existing Communities Lowering memory requirements by replacing Schematron HTML5 Parsing in Gecko: A Build Introducing SAX Tree NVDL Support in Validator.nu HOWTO Avoid Being Called a Bozo When Producing XML An Unofficial Q&A about the Discontinuation of the XHTML2 WG Thoughts on HTML5 Becoming a W3C Recommendation Four Finnish Banks Training Users to Give Banking Credentials to Another Site Unimpressed by Leopard Sergeant Semantics The Content Sink Inheritance Diagram – 2006-06-30 What is EME? About Points and Pixels as Units The Performance Cost of the HTML Tree Builder Social Media Impression Management The spacer Element Is Gone Openmind 2006 Performance Mistake XHTML and Mobile Devices WebM-Enabled Browser Usage Share Exceeds H.264-Enabled Browser Usage Share on Desktop (in StatCounter Numbers) HTML5 Parser-Based View Source Syntax Highlighting Vendor Prefixes Are Hurting the Web Accept-Charset Is No More Dualroids Writing Structural Stylable Document in Mozilla Editor ISO-8859-15 on haitallinen Hourglass The Scientific Method According to Hixie Maemo Source Code Karpelan lukkovertaus ontuu Digitaalisesta arkistoinnista ARIA in HTML5 Integration: Document Conformance (Draft) XHTML—What’s the Point? (Draft, incomplete) Mac OS X Browser Comparison HOWTO Spot a Wannabe Web Standards Advocate An Idea About Intermediate Language Trees and Web UI Generation Thoughts on Using SSL/TLS Certificates as the Solution to Phishing Bureaucracy Meets the Web Europe Day HOWTO Establish a 100% Literacy Rate What to Do with All These Photos? Charmod Norm Checking Validator Web Service Interface Ideas DTDs Don’t Work on the Web EFFI’s Day in Court
Regular Expressions, Computer Science and Practice
Henri Sivonen · 2011-12-22 · via Henri Sivonen’s pages

“What does all this mean to you, as a user? Absolutely nothing. As a user, you don't care if it's regular, nonregular, unregular, irregular, or incontinent. So long as you know what you can expect from it (something this chapter will show you), you know all you need to care about.”

Jeffrey Friedl, author of Mastering Regular Expressions, under the heading “NFA: Theory vs. Reality”

Theory—Education

My computer science curriculum included a course on compilers. We were taught that you can turn a regular expression into an NFA using Thompson’s Construction. We were also taught that you can convert any NFA into a DFA that you can actually run. It all made sense.

I knew that Perlish “regular expressions” aren’t really regular expressions in the computer science sense, but I thought that the implementors knew what they were doing and the extensions somehow fit nicely into the model of compiling into a DFA by using an NFA as an intermediate step. I sincerely thought that the explicit pattern compilation step in Java and Python built a reusable DFA representation that’d guarantee constant-space and O(n) time (where n is the length of the string being matched) when actually running the matcher.

I was so naïve.

Reality—Stack Trace

Validator.nu uses the Xerces regular expression implementation when XSD regular expressions are used in a RELAX NG schema. Validator.nu also sends me email when the validation engine crashes. (Thanks to a managed runtime, this doesn’t crash the app or even make the thread die.)

I got email that indicated that someone used the CMLComp Validator to check a CML file using Validator.nu as the back end and Validator.nu experienced a stack overflow:

java.lang.StackOverflowError
        at org.apache.xerces.impl.xpath.regex.RegularExpression.matchString(Unknown Source)
        at org.apache.xerces.impl.xpath.regex.RegularExpression.matchString(Unknown Source)
        at org.apache.xerces.impl.xpath.regex.RegularExpression.matchString(Unknown Source)

And the same line just repeats over and over until the log4j emailer cutoff.

This clearly shows that the regular expression matching stage is recursive. Moreover, the depth of recursion depends on the CML document containing the string being matched and not the schema containing the regular expression. Otherwise, the stack would overflow all the time.

This doesn’t look like DFA constant-space and O(n) time behavior. Hmm…

Explanation—Paper

Via Tim Bray, I stumbled upon a paper that explains this all. The popular regular expression implementations that have capturing groups and, more importantly, back-references to these groups use a recursive implementation on the NFA without converting to a DFA and this recursive implementation has dramatically worse worst-case space and time complexity at match time than a DFA. Oops.

One might argue that taking something that is already very useful with an O(n) implementation and adding a feature that makes it O(2n)—even if only in the worse case—is a bad idea. And even if that additional feature itself is useful when you need it, it is still bad to have to risk exponential behavior when you are not using that feature.

What is particularly annoying in the case of XSD regular expressions is that XSD regular expressions are actually pure regular expressions without back-references. In fact, they don’t even have capturing groups. They are purely about testing whether a string belongs in the regular language expressed by the regular expression. Taken on their own right, it makes no sense to implement XSD regular expressions using the exponential recursive algorithm that makes sense with back-references.

XSD regular expressions are not taken on their own right in Xerces, though. Instead, a more general regular expression engine is adapted to implement XSD regular expressions and, therefore, XSD regular expressions suffer from the latent back-referencing ability of the engine.

LazyWeb Request

If you have an open-source Unicode regular expression engine written in Java that compiles the pattern into a thread-safe DFA against which multiple matchers can run concurrently later, please let me know. Even better if the engine already complies with the XSD regular expression syntax. (Implementation note for porting old C implementations: Traditional 256-entry next-transition tables don’t work with Unicode, and transitions probably need to be labeled by something like ICU4J UnicodeSet objects.)

Update: It was pointed out to me that byte-oriented approaches do work with UTF-8. Indeed, I should have mentioned that the matcher could run on UTF-8 string representation but I thought character classes would behave badly in that case. I do not know if there’d be actual badness with character classes and most schema regular expressions are probably want to match Basic Latin anyway. (Except with XSD regular expressions it is easy to match more by accident—for example, the definition of \s is politically correct but not that practical.)

Update: The LazyWeb request above worked. I have been informed that there is an Open Source DFA regular expression implementation for Java.

Update: Björn Höhrmann has created Open Source DFA recognizer operating on UTF-8 for recognizing sets of Unicode characters for Perl.