From 3674f7c0f90314a363f4205b374a90c5a1daa22b Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <holger@freyther.de>
Date: Sun, 8 Dec 2013 20:22:17 +0100
Subject: [PATCH] kernel: Fix IndexOutOfRange with empty matches in the regexp

It is possible to have a non nil Interval that is empty. Make
the code work on isNil or isEmpty to avoid the exception It
might be that the Intervals of registers might never be nil.

Fixes:
SystemExceptions.IndexOutOfRange(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.IndexOutOfRange class>>signalOn:withIndex: (SysExcept.st:660)
Interval>>first (Interval.st:245)
Kernel.MatchingRegexResults>>at: (Regex.st:382)

2013-12-08  Holger Hans Peter Freyther  <holger@freyther.de>

	* kernel/Regex.st: Check for isEmpty of the Interval before
	trying to use it.

2013-12-08  Holger Hans Peter Freyther <holger@freyther.de>

	* kernel/RegexpTests.st: Add tests for Regexp.
---
 ChangeLog                                   |  5 +++++
 kernel/Regex.st                             |  2 +-
 packages/kernel-tests/ChangeLog             |  4 ++++
 packages/kernel-tests/Makefile.frag         |  2 +-
 packages/kernel-tests/kernel/RegexpTests.st | 34 +++++++++++++++++++++++++++++
 packages/kernel-tests/package.xml           |  2 ++
 6 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 packages/kernel-tests/kernel/RegexpTests.st

diff --git a/ChangeLog b/ChangeLog
index f13c48b..d41d18a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-08  Holger Hans Peter Freyther  <holger@freyther.de>
+
+	* kernel/Regex.st: Check for isEmpty of the Interval before
+	trying to use it.
+
 2013-10-21  Gwenael Casaccio  <gwenael.casaccio@gmail.com>
 
 	* kernel/ContextPart.st: Print the instruction pointer value in the
diff --git a/kernel/Regex.st b/kernel/Regex.st
index 91a4ab3..2d77884 100644
--- a/kernel/Regex.st
+++ b/kernel/Regex.st
@@ -377,7 +377,7 @@ RegexResults subclass: MatchingRegexResults [
 	(cache at: anIndex) isNil 
 	    ifTrue: 
 		[reg := registers at: anIndex.
-		text := reg isNil 
+		text := (reg isNil or: [reg isEmpty])
 			    ifTrue: [nil]
 			    ifFalse: [self subject copyFrom: reg first to: reg last].
 		cache at: anIndex put: text].
diff --git a/packages/kernel-tests/ChangeLog b/packages/kernel-tests/ChangeLog
index 1824b15..e611d4b 100644
--- a/packages/kernel-tests/ChangeLog
+++ b/packages/kernel-tests/ChangeLog
@@ -1,3 +1,7 @@
+2013-12-08  Holger Hans Peter Freyther <holger@freyther.de>
+
+	* kernel/RegexpTests.st: Add tests for Regexp.
+
 2013-10-12  Gwenael Casaccio <gwenael.casaccio@gmail.com>
             Paolo Bonzini <bonzini@gnu.org>
 
diff --git a/packages/kernel-tests/Makefile.frag b/packages/kernel-tests/Makefile.frag
index b3d3719..0748652 100644
--- a/packages/kernel-tests/Makefile.frag
+++ b/packages/kernel-tests/Makefile.frag
@@ -1,5 +1,5 @@
 Kernel-Tests_FILES = \
-packages/kernel-tests/ChangeLog packages/kernel-tests/kernel/CompiledMethodTests.st packages/kernel-tests/kernel/ContextPartTests.st packages/kernel-tests/kernel/ObjectTests.st 
+packages/kernel-tests/ChangeLog packages/kernel-tests/kernel/CompiledMethodTests.st packages/kernel-tests/kernel/ContextPartTests.st packages/kernel-tests/kernel/ObjectTests.st packages/kernel-tests/kernel/RegexpTests.st 
 $(Kernel-Tests_FILES):
 $(srcdir)/packages/kernel-tests/stamp-classes: $(Kernel-Tests_FILES)
 	touch $(srcdir)/packages/kernel-tests/stamp-classes
diff --git a/packages/kernel-tests/kernel/RegexpTests.st b/packages/kernel-tests/kernel/RegexpTests.st
new file mode 100644
index 0000000..fe98981
--- /dev/null
+++ b/packages/kernel-tests/kernel/RegexpTests.st
@@ -0,0 +1,34 @@
+TestCase subclass: TestRegexp [
+
+    testEmptyMatch [
+        | data match |
+
+	data := '""'.
+	match := (data =~ '"([^"]*)"').
+
+        "Check that it has matched"
+        self assert: match class equals: Kernel.MatchingRegexResults.
+        self assert: match matched.
+        self assert: match size = 1.
+        self assert: (match at: 1) equals: nil.
+
+        "Check if an exception is thrown"
+        self shouldnt: [match printString] raise: Exception.
+    ]
+
+    testMatch [
+        | data match |
+
+	data := '"A"'.
+	match := (data =~ '"([^"]*)"').
+
+        "Check that it has matched"
+        self assert: match class equals: Kernel.MatchingRegexResults.
+        self assert: match matched.
+        self assert: match size = 1.
+        self assert: (match at: 1) equals: 'A'.
+
+        "Check if an exception is thrown"
+        self shouldnt: [match printString] raise: Exception.
+    ]
+]
diff --git a/packages/kernel-tests/package.xml b/packages/kernel-tests/package.xml
index 77273b1..61d9d8a 100644
--- a/packages/kernel-tests/package.xml
+++ b/packages/kernel-tests/package.xml
@@ -5,9 +5,11 @@
    <sunit>TestCompiledMethod</sunit>
    <sunit>TestContextPart</sunit>
    <sunit>TestObject</sunit>
+   <sunit>TestRegexp</sunit>
    <filein>kernel/CompiledMethodTests.st</filein>
    <filein>kernel/ContextPartTests.st</filein>
    <filein>kernel/ObjectTests.st</filein>
+   <filein>kernel/RegexpTests.st</filein>
   </test>
 
   <file>ChangeLog</file>
-- 
1.8.4.rc3

