Skip to content

Commit 58dde88

Browse files
DenisUngemachBeckerWdf
authored andcommitted
TextMergeView Unhandled IndexOutOfBoundsException at lines height calc
In the TextMergeViewer the method getHeightBetweenLines(MergeSourceViewer tp, int fromLine, int toLine) was be called with a higher toLine value than the number of lines in the TextWidget. The reason was that there can be a document region offset, which was not handled. This can be checked with the example here: #1542 which is the compare of java methods. Solution: handle the document region offset before getHeightBetweenLines will be called. In getHeightBetweenLines we should prevent an index out of bounds exception with a fallback logic. This could lead to wrong paintings, but this is better than a RuntimeException. Previously in the shift calculation also the document region offset was handled. But now the heights of lines can be flexible, so this calculation doesn't makes sense anymore for us. Fixes #1536 Signed-off-by: Denis Ungemach <[email protected]>
1 parent 75d509d commit 58dde88

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

team/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,7 +2251,7 @@ private Diff handleMouseInSides(Canvas canvas, MergeSourceViewer tp, int my) {
22512251
return null;
22522252

22532253
if (fMerger.hasChanges()) {
2254-
int shift= tp.getVerticalScrollOffset() + (2-LW);
2254+
int shift = calculateShift(tp) + (2 - LW);
22552255

22562256
Point region= new Point(0, 0);
22572257
char leg = getLeg(tp);
@@ -2264,6 +2264,7 @@ private Diff handleMouseInSides(Canvas canvas, MergeSourceViewer tp, int my) {
22642264
continue;
22652265

22662266
tp.getLineRange(diff.getPosition(leg), region);
2267+
region.x -= tp.getDocumentRegionOffset();
22672268
int y = getHeightBetweenLines(tp, 0, region.x) + shift;
22682269
int h = getHeightBetweenLines(tp, region.x, region.x + region.y);
22692270

@@ -2293,8 +2294,8 @@ private Diff getDiffUnderMouse(Canvas canvas, int mx, int my, Rectangle r) {
22932294
return null;
22942295

22952296
if (fMerger.hasChanges()) {
2296-
int lshift= fLeft.getVerticalScrollOffset();
2297-
int rshift= fRight.getVerticalScrollOffset();
2297+
int lshift = calculateShift(fLeft);
2298+
int rshift = calculateShift(fRight);
22982299

22992300
Point region= new Point(0, 0);
23002301

@@ -2307,10 +2308,12 @@ private Diff getDiffUnderMouse(Canvas canvas, int mx, int my, Rectangle r) {
23072308
continue;
23082309

23092310
fLeft.getLineRange(diff.getPosition(LEFT_CONTRIBUTOR), region);
2311+
region.x -= fLeft.getDocumentRegionOffset();
23102312
int ly = getHeightBetweenLines(fLeft, 0, region.x) + lshift;
23112313
int lh = getHeightBetweenLines(fLeft, region.x, region.x + region.y);
23122314

23132315
fRight.getLineRange(diff.getPosition(RIGHT_CONTRIBUTOR), region);
2316+
region.x -= fRight.getDocumentRegionOffset();
23142317
int ry = getHeightBetweenLines(fRight, 0, region.x) + rshift;
23152318
int rh = getHeightBetweenLines(fRight, region.x, region.x + region.y);
23162319

@@ -4222,6 +4225,9 @@ private void updateLines(IDocument d) {
42224225
* @return
42234226
*/
42244227
private int getHeightBetweenLines(MergeSourceViewer tp, int fromLine, int toLine) {
4228+
4229+
if (fromLine == toLine)
4230+
return 0;
42254231
StyledText w = tp.getSourceViewer().getTextWidget();
42264232
List<Integer> lineHeights = this.lineHeightsByViewer.get(tp);
42274233
if (lineHeights == null) {
@@ -4236,7 +4242,16 @@ private int getHeightBetweenLines(MergeSourceViewer tp, int fromLine, int toLine
42364242
}
42374243
});
42384244
}
4245+
42394246
int lineSpacing = w.getLineSpacing();
4247+
4248+
// If the linenumber is higher than the number of lines, we should prevent an
4249+
// IndexOutOfBoundsException
4250+
if (toLine > w.getLineCount()){
4251+
int lineHeight = tp.getSourceViewer().getTextWidget().getLineHeight();
4252+
return (toLine - fromLine) * (lineHeight + w.getLineVerticalIndent(0)) + lineSpacing;
4253+
}
4254+
42404255
int height = 0;
42414256
for (int i = fromLine; i < toLine; i++) {
42424257
Integer heightAtLine = lineHeights.get(i);
@@ -4317,8 +4332,8 @@ private void paintCenter(Canvas canvas, GC g) {
43174332
return;
43184333

43194334
if (fMerger.hasChanges()) {
4320-
int lshift= fLeft.getVerticalScrollOffset();
4321-
int rshift= fRight.getVerticalScrollOffset();
4335+
int lshift = calculateShift(fLeft);
4336+
int rshift = calculateShift(fRight);
43224337

43234338
Point region= new Point(0, 0);
43244339

@@ -4332,10 +4347,12 @@ private void paintCenter(Canvas canvas, GC g) {
43324347
continue;
43334348

43344349
fLeft.getLineRange(diff.getPosition(LEFT_CONTRIBUTOR), region);
4350+
region.x -= fLeft.getDocumentRegionOffset();
43354351
int ly = getHeightBetweenLines(fLeft, 0, region.x) + lshift;
43364352
int lh = getHeightBetweenLines(fLeft, region.x, region.x + region.y);
43374353

43384354
fRight.getLineRange(diff.getPosition(RIGHT_CONTRIBUTOR), region);
4355+
region.x -= fRight.getDocumentRegionOffset();
43394356
int ry = getHeightBetweenLines(fRight, 0, region.x) + rshift;
43404357
int rh = getHeightBetweenLines(fRight, region.x, region.x + region.y);
43414358

@@ -4436,6 +4453,10 @@ private void buildBaseCenterCurve(int w) {
44364453
}
44374454
}
44384455

4456+
private int calculateShift(MergeSourceViewer tp) {
4457+
return tp.getSourceViewer().getTopInset() - tp.getSourceViewer().getTextWidget().getTopPixel();
4458+
}
4459+
44394460
private void paintSides(GC g, MergeSourceViewer tp, Canvas canvas, boolean right) {
44404461

44414462
Display display= canvas.getDisplay();
@@ -4462,7 +4483,7 @@ private void paintSides(GC g, MergeSourceViewer tp, Canvas canvas, boolean right
44624483

44634484
if (fMerger.hasChanges()) {
44644485
boolean allOutgoing = allOutgoing();
4465-
int shift= tp.getVerticalScrollOffset() + (2-LW);
4486+
int shift = calculateShift(tp) + (2 - LW);
44664487

44674488
Point region= new Point(0, 0);
44684489
char leg = getLeg(tp);
@@ -4475,6 +4496,7 @@ private void paintSides(GC g, MergeSourceViewer tp, Canvas canvas, boolean right
44754496
continue;
44764497

44774498
tp.getLineRange(diff.getPosition(leg), region);
4499+
region.x -= tp.getDocumentRegionOffset();
44784500
int y = getHeightBetweenLines(tp, 0, region.x) + shift;
44794501
int h = getHeightBetweenLines(tp, region.x, region.x + region.y);
44804502

@@ -4522,7 +4544,7 @@ private void paint(PaintEvent event, MergeSourceViewer tp) {
45224544
Display display= canvas.getDisplay();
45234545

45244546
int w= canvas.getSize().x;
4525-
int shift= tp.getVerticalScrollOffset() + (2-LW);
4547+
int shift = calculateShift(tp) + (2 - LW);
45264548
int maxh= event.y+event.height; // visibleHeight
45274549

45284550
shift += fTopInset;
@@ -4540,6 +4562,7 @@ private void paint(PaintEvent event, MergeSourceViewer tp) {
45404562
continue;
45414563

45424564
tp.getLineRange(diff.getPosition(leg), range);
4565+
range.x -= tp.getDocumentRegionOffset();
45434566
int y = getHeightBetweenLines(tp, 0, range.x) + shift;
45444567
int h = getHeightBetweenLines(tp, range.x, range.x + range.y);
45454568

0 commit comments

Comments
 (0)