diff options
author | Shawn O. Pearce <sop@google.com> | 2009-06-01 17:13:06 -0700 |
---|---|---|
committer | Shawn O. Pearce <sop@google.com> | 2009-06-01 17:13:06 -0700 |
commit | 43c0c4abf10b03a67d199b45260f172f666149a6 (patch) | |
tree | 73b3bae4f370ddc81a2fb5084e935695fb920091 | |
parent | 578ebd876669747f243db23a18a515b3de2672c2 (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.java | 36 |
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); } } } |