summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-06-01 17:13:06 -0700
committerShawn O. Pearce <sop@google.com>2009-06-01 17:13:06 -0700
commit43c0c4abf10b03a67d199b45260f172f666149a6 (patch)
tree73b3bae4f370ddc81a2fb5084e935695fb920091
parent578ebd876669747f243db23a18a515b3de2672c2 (diff)
Fix StackOverflowError during cherry-pick submit
Using a regex pattern of "^(\n|.)*\n..." causes the Java regex package to recurse for each consideration of the first alternation, creating a very deep stack for a relatively short commit message. If the message is large enough, the thread stack overflows, and an exception is thrown. Instead we use a more customized parser, to examine the message end and determine if an LF should be appended, or not. Bug: GERRIT-207 Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--src/main/java/com/google/gerrit/git/MergeOp.java36
1 files changed, 29 insertions, 7 deletions
diff --git a/src/main/java/com/google/gerrit/git/MergeOp.java b/src/main/java/com/google/gerrit/git/MergeOp.java
index 5dcd27d7da..0f09e6d069 100644
--- a/src/main/java/com/google/gerrit/git/MergeOp.java
+++ b/src/main/java/com/google/gerrit/git/MergeOp.java
@@ -502,7 +502,7 @@ public class MergeOp {
// Missing a trailing LF? Correct it (perhaps the editor was broken).
msgbuf.append('\n');
}
- if (!msgbuf.toString().matches("^(\n|.)*\n[A-Za-z0-9-]{1,}: [^\n]{1,}\n$")) {
+ if (!endsWithKey(msgbuf.toString())) {
// Doesn't end in a "Signed-off-by: ..." style line? Add another line
// break to start a new paragraph for the reviewed-by tag lines.
//
@@ -623,6 +623,24 @@ public class MergeOp {
newCommits.put(n.patchsetId.getParentKey(), mergeTip);
}
+ private boolean endsWithKey(final String msg) {
+ if (msg.length() == 0 || !msg.endsWith("\n") || msg.length() < 2) {
+ return false;
+ }
+
+ final int lf = msg.lastIndexOf('\n', msg.length() - 2);
+ if (lf == -1) {
+ return false;
+ }
+
+ final String line = msg.substring(lf + 1);
+ final int c = line.indexOf(':');
+ if (c == -1) {
+ return false;
+ }
+ return line.substring(0, c).matches("[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]");
+ }
+
private void updateBranch() throws MergeException {
if (branchTip == null || branchTip != mergeTip) {
branchUpdate.setForceUpdate(false);
@@ -712,14 +730,16 @@ public class MergeOp {
final MergeFailSender cm = new MergeFailSender(server, c);
cm.setFrom(getSubmitter(c));
cm.setReviewDb(schema);
- cm.setPatchSet(schema.patchSets().get(c.currentPatchSetId()), schema
- .patchSetInfo().get(c.currentPatchSetId()));
+ cm.setPatchSet(schema.patchSets().get(c.currentPatchSetId()),
+ schema.patchSetInfo().get(c.currentPatchSetId()));
cm.setChangeMessage(msg);
cm.send();
} catch (OrmException e) {
- log.error("Cannot submit patch set for Change " + c.getId() + " due to a missing dependency.", e);
+ log.error("Cannot submit patch set for Change " + c.getId()
+ + " due to a missing dependency.", e);
} catch (EmailException e) {
- log.error("Cannot submit patch set for Change " + c.getId() + " due to a missing dependency.", e);
+ log.error("Cannot submit patch set for Change " + c.getId()
+ + " due to a missing dependency.", e);
}
break;
@@ -871,9 +891,11 @@ public class MergeOp {
cm.setChangeMessage(msg);
cm.send();
} catch (OrmException e) {
- log.error("Cannot submit patch set for Change " + c.getId() + " due to a path conflict.", e);
+ log.error("Cannot submit patch set for Change " + c.getId()
+ + " due to a path conflict.", e);
} catch (EmailException e) {
- log.error("Cannot submit patch set for Change " + c.getId() + " due to a path conflict.", e);
+ log.error("Cannot submit patch set for Change " + c.getId()
+ + " due to a path conflict.", e);
}
}
}