@@ -366,10 +366,13 @@ func (dmp *DiffMatchPatch) diffLineMode(text1, text2 string, deadline time.Time)
366
366
// and return the recursively constructed diff.
367
367
// See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.
368
368
func (dmp * DiffMatchPatch ) DiffBisect (text1 , text2 string , deadline time.Time ) []Diff {
369
+ // Convert to runes to avoid utf8 slicing bugs.
370
+ runes1 := []rune (text1 )
371
+ runes2 := []rune (text2 )
369
372
// Cache the text lengths to prevent multiple calls.
370
- text1_len , text2_len := len (text1 ), len (text2 )
373
+ runes1_len , runes2_len := len (runes1 ), len (runes2 )
371
374
372
- max_d := (text1_len + text2_len + 1 ) / 2
375
+ max_d := (runes1_len + runes2_len + 1 ) / 2
373
376
v_offset := max_d
374
377
v_length := 2 * max_d
375
378
@@ -382,7 +385,7 @@ func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) [
382
385
v1 [v_offset + 1 ] = 0
383
386
v2 [v_offset + 1 ] = 0
384
387
385
- delta := text1_len - text2_len
388
+ delta := runes1_len - runes2_len
386
389
// If the total number of characters is odd, then the front path will collide
387
390
// with the reverse path.
388
391
front := (delta % 2 != 0 )
@@ -410,30 +413,28 @@ func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) [
410
413
}
411
414
412
415
y1 := x1 - k1
413
- for x1 < text1_len && y1 < text2_len {
414
- r1 , size := utf8 .DecodeRuneInString (text1 [x1 :])
415
- r2 , _ := utf8 .DecodeRuneInString (text2 [y1 :])
416
- if r1 != r2 {
416
+ for x1 < runes1_len && y1 < runes2_len {
417
+ if runes1 [x1 ] != runes2 [y1 ] {
417
418
break
418
419
}
419
- x1 += size
420
- y1 += size
420
+ x1 ++
421
+ y1 ++
421
422
}
422
423
v1 [k1_offset ] = x1
423
- if x1 > text1_len {
424
+ if x1 > runes1_len {
424
425
// Ran off the right of the graph.
425
426
k1end += 2
426
- } else if y1 > text2_len {
427
+ } else if y1 > runes2_len {
427
428
// Ran off the bottom of the graph.
428
429
k1start += 2
429
430
} else if front {
430
431
k2_offset := v_offset + delta - k1
431
432
if k2_offset >= 0 && k2_offset < v_length && v2 [k2_offset ] != - 1 {
432
433
// Mirror x2 onto top-left coordinate system.
433
- x2 := text1_len - v2 [k2_offset ]
434
+ x2 := runes1_len - v2 [k2_offset ]
434
435
if x1 >= x2 {
435
436
// Overlap detected.
436
- return dmp .diffBisectSplit_ (text1 , text2 , x1 , y1 , deadline )
437
+ return dmp .diffBisectSplit_ (runes1 , runes2 , x1 , y1 , deadline )
437
438
}
438
439
}
439
440
}
@@ -448,20 +449,18 @@ func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) [
448
449
x2 = v2 [k2_offset - 1 ] + 1
449
450
}
450
451
var y2 = x2 - k2
451
- for x2 < text1_len && y2 < text2_len {
452
- r1 , size := utf8 .DecodeLastRuneInString (text1 [:text1_len - x2 ])
453
- r2 , _ := utf8 .DecodeLastRuneInString (text2 [:text2_len - y2 ])
454
- if r1 != r2 {
452
+ for x2 < runes1_len && y2 < runes2_len {
453
+ if runes1 [runes1_len - x2 - 1 ] != runes2 [runes2_len - y2 - 1 ] {
455
454
break
456
455
}
457
- x2 += size
458
- y2 += size
456
+ x2 ++
457
+ y2 ++
459
458
}
460
459
v2 [k2_offset ] = x2
461
- if x2 > text1_len {
460
+ if x2 > runes1_len {
462
461
// Ran off the left of the graph.
463
462
k2end += 2
464
- } else if y2 > text2_len {
463
+ } else if y2 > runes2_len {
465
464
// Ran off the top of the graph.
466
465
k2start += 2
467
466
} else if ! front {
@@ -470,10 +469,10 @@ func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) [
470
469
x1 := v1 [k1_offset ]
471
470
y1 := v_offset + x1 - k1_offset
472
471
// Mirror x2 onto top-left coordinate system.
473
- x2 = text1_len - x2
472
+ x2 = runes1_len - x2
474
473
if x1 >= x2 {
475
474
// Overlap detected.
476
- return dmp .diffBisectSplit_ (text1 , text2 , x1 , y1 , deadline )
475
+ return dmp .diffBisectSplit_ (runes1 , runes2 , x1 , y1 , deadline )
477
476
}
478
477
}
479
478
}
@@ -487,16 +486,16 @@ func (dmp *DiffMatchPatch) DiffBisect(text1, text2 string, deadline time.Time) [
487
486
}
488
487
}
489
488
490
- func (dmp * DiffMatchPatch ) diffBisectSplit_ (text1 , text2 string , x , y int ,
489
+ func (dmp * DiffMatchPatch ) diffBisectSplit_ (runes1 , runes2 [] rune , x , y int ,
491
490
deadline time.Time ) []Diff {
492
- text1a := text1 [:x ]
493
- text2a := text2 [:y ]
494
- text1b := text1 [x :]
495
- text2b := text2 [y :]
491
+ runes1a := runes1 [:x ]
492
+ runes2a := runes2 [:y ]
493
+ runes1b := runes1 [x :]
494
+ runes2b := runes2 [y :]
496
495
497
496
// Compute both diffs serially.
498
- diffs := dmp .diffMain (text1a , text2a , false , deadline )
499
- diffsb := dmp .diffMain (text1b , text2b , false , deadline )
497
+ diffs := dmp .diffMain (string ( runes1a ), string ( runes2a ) , false , deadline )
498
+ diffsb := dmp .diffMain (string ( runes1b ), string ( runes2b ) , false , deadline )
500
499
501
500
return append (diffs , diffsb ... )
502
501
}
0 commit comments