enhanced xmlFARegExec range evaluation for min occurs 0 problems - fixes

* xmlregexp.c: enhanced xmlFARegExec range evaluation for min
  occurs 0 problems - fixes bug 140478.
diff --git a/xmlregexp.c b/xmlregexp.c
index d1e6f38..484c76e 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -2235,12 +2235,24 @@
 	xmlRegAtomPtr atom;
 
 	/*
-	 * End of input on non-terminal state, rollback, however we may
+	 * If end of input on non-terminal state, rollback, however we may
 	 * still have epsilon like transition for counted transitions
-	 * on counters, in that case don't break too early.
+	 * on counters, in that case don't break too early.  Additionally,
+	 * if we are working on a range like "AB{0,2}", where B is not present,
+	 * we don't want to break.
 	 */
-	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
-	    goto rollback;
+	if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL)) {
+	    /* must check if atom allows minOccurs of 0 */
+	    if (exec->transno < exec->state->nbTrans) { /* there is a transition */
+	        trans = &exec->state->trans[exec->transno];
+		if (trans->to >=0) {
+		    atom = trans->atom;
+		    if (!((atom->min == 0) && (atom->max > 0)))
+		        goto rollback;
+		}
+	    } else
+	        goto rollback;
+	}
 
 	exec->transcount = 0;
 	for (;exec->transno < exec->state->nbTrans;exec->transno++) {
@@ -2271,7 +2283,7 @@
 	    } else if (exec->inputString[exec->index] != 0) {
                 codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
 		ret = xmlRegCheckCharacter(atom, codepoint);
-		if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
+		if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) {
 		    xmlRegStatePtr to = comp->states[trans->to];
 
 		    /*
@@ -2326,7 +2338,21 @@
 		    if (ret == 0) {
 			goto rollback;
 		    }
+		} else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) {
+		    /*
+		     * we don't match on the codepoint, but minOccurs of 0
+		     * says that's ok.  Setting len to 0 inhibits stepping
+		     * over the codepoint.
+		     */
+		    exec->transcount = 1;
+		    len = 0;
+		    ret = 1;
 		}
+	    } else if ((atom->min == 0) && (atom->max > 0)) {
+	        /* another spot to match when minOccurs is 0 */
+		exec->transcount = 1;
+		len = 0;
+		ret = 1;
 	    }
 	    if (ret == 1) {
 		if (exec->state->nbTrans > exec->transno + 1) {