Skip to content

Commit

Permalink
SF-2905 Fix crash when syncing a book with invalid chapters (#2660)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmachapman authored Aug 19, 2024
1 parent 8ba4ea8 commit 0d9b08d
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 33 deletions.
5 changes: 5 additions & 0 deletions src/SIL.XForge.Scripture/Services/DeltaUsxMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,11 @@ public XDocument ToUsx(XDocument oldUsxDoc, IEnumerable<ChapterDelta> chapterDel
}
}

if (i >= chapterDeltaArray.Length)
{
return newUsxDoc;
}

if (
chapterDeltaArray[i].Number == curChapter
&& chapterDeltaArray[i].IsValid
Expand Down
76 changes: 43 additions & 33 deletions test/SIL.XForge.Scripture.Tests/Services/DeltaUsxMapperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,47 @@ public void ToUsx_EmptySegments()
Assert.IsTrue(XNode.DeepEquals(newUsxDoc, expected));
}

[Test]
public void ToUsx_InvalidChapters()
{
// Set up a USX document with two invalid chapters
XDocument usxDoc = Usx(
"RUT",
null,
"3.0",
Chapter("1"),
Verse("1"),
Chapter("2."),
Verse("1"),
Chapter("3"),
Verse("1"),
Chapter("4."),
Verse("1")
);

var mapper = new DeltaUsxMapper(_mapperGuidService, _logger, _exceptionHandler);

// Get the chapter deltas, which will be the valid chapters
List<ChapterDelta> chapterDeltas = mapper.ToChapterDeltas(usxDoc).ToList();

var expected1 = Delta.New().InsertChapter("1").InsertVerse("1").InsertBlank("verse_1_1").InsertText("\n");
var expected2 = Delta.New().InsertChapter("3").InsertVerse("1").InsertBlank("verse_3_1").InsertText("\n");

Assert.That(chapterDeltas[0].Number, Is.EqualTo(1));
Assert.That(chapterDeltas[0].LastVerse, Is.EqualTo(1));
Assert.That(chapterDeltas[0].IsValid, Is.True);
Assert.IsTrue(chapterDeltas[0].Delta.DeepEquals(expected1));

Assert.That(chapterDeltas[1].Number, Is.EqualTo(3));
Assert.That(chapterDeltas[1].LastVerse, Is.EqualTo(1));
Assert.That(chapterDeltas[1].IsValid, Is.True);
Assert.IsTrue(chapterDeltas[1].Delta.DeepEquals(expected2));

// Ensure that the USX round trips perfectly
XDocument newUsxDoc = mapper.ToUsx(usxDoc, chapterDeltas);
Assert.IsTrue(XNode.DeepEquals(newUsxDoc, usxDoc));
}

[Test]
public void ToUsx_CharText()
{
Expand Down Expand Up @@ -1223,37 +1264,6 @@ public void ToUsx_MismatchNoChapters_UnchangedUsx()
.ReportException(Arg.Is<Exception>((Exception e) => e.Message.Contains("no real chapters")));
}

[Test]
public void ToUsx_MismatchedChapters_UnchangedUsx()
{
_exceptionHandler.ClearReceivedCalls();
var chapterDeltas = new[]
{
new ChapterDelta(
1,
0,
true,
new Delta().InsertChapter("1").InsertBlank("p_1").InsertVerse("1").InsertBlank("verse_1_1")
)
};

var mapper = new DeltaUsxMapper(_mapperGuidService, _logger, _exceptionHandler);

// The USX here has chapter 2, which is not in chapterDeltas. The chapterDeltas does contain 1 real chapter.
XDocument input = Usx(
"PHM",
Chapter("1"),
Para("p", Verse("1"), "Verse text."),
Chapter("2"),
Para("p", Verse("1"), "Verse text.")
);

// SUT
Exception thrown = Assert.Throws<Exception>(() => mapper.ToUsx(input, chapterDeltas));
Assert.That(thrown.Message, Contains.Substring("Rethrowing"));
Assert.That(thrown.InnerException, Is.TypeOf<IndexOutOfRangeException>());
}

[Test]
public void ToUsx_BlankLine()
{
Expand Down Expand Up @@ -3605,8 +3615,8 @@ public void Roundtrip_NestedChars()
AssertRoundtrips(
"""
\id PHM
\c 1
\p
\c 1
\p
\v 1 \bd \+sup 1\+sup* This is\+sup 2\+sup* bold text.\+sup 3\+sup* \bd* This is normal text.
"""
);
Expand Down

0 comments on commit 0d9b08d

Please sign in to comment.