mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
LibDiff: Fix wrong index used when prepending context lines
`i` is used as the index for 'old lines' in diff generation, not 'new lines'. Using the wrong index would mean that for certain diffs the prefixed context information would have wrong content, and could even result in a crash. Fix this, and add a test for an input which was previously crashing.
This commit is contained in:
parent
4adbf1d041
commit
b738929195
Notes:
sideshowbarker
2024-07-17 03:51:15 +09:00
Author: https://github.com/shannonbooth Commit: https://github.com/SerenityOS/serenity/commit/b738929195 Pull-request: https://github.com/SerenityOS/serenity/pull/21010
4 changed files with 117 additions and 1 deletions
|
@ -5,6 +5,7 @@ add_subdirectory(LibC)
|
||||||
add_subdirectory(LibCompress)
|
add_subdirectory(LibCompress)
|
||||||
add_subdirectory(LibCore)
|
add_subdirectory(LibCore)
|
||||||
add_subdirectory(LibCpp)
|
add_subdirectory(LibCpp)
|
||||||
|
add_subdirectory(LibDiff)
|
||||||
add_subdirectory(LibEDID)
|
add_subdirectory(LibEDID)
|
||||||
add_subdirectory(LibELF)
|
add_subdirectory(LibELF)
|
||||||
add_subdirectory(LibGfx)
|
add_subdirectory(LibGfx)
|
||||||
|
|
7
Tests/LibDiff/CMakeLists.txt
Normal file
7
Tests/LibDiff/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
set(TEST_SOURCES
|
||||||
|
TestDiff.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(source IN LISTS TEST_SOURCES)
|
||||||
|
serenity_test("${source}" LibDiff LIBS LibDiff)
|
||||||
|
endforeach()
|
108
Tests/LibDiff/TestDiff.cpp
Normal file
108
Tests/LibDiff/TestDiff.cpp
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/MemoryStream.h>
|
||||||
|
#include <LibDiff/Format.h>
|
||||||
|
#include <LibDiff/Generator.h>
|
||||||
|
#include <LibTest/TestCase.h>
|
||||||
|
|
||||||
|
TEST_CASE(test_generate_unified_diff)
|
||||||
|
{
|
||||||
|
StringView old_text = R"(Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x150 children: not-inline
|
||||||
|
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <div> at (8,8) content-size 784x150 children: inline
|
||||||
|
line 0 width: 300, height: 150, bottom: 150, baseline: 150
|
||||||
|
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 300x150]
|
||||||
|
TextNode <#text>
|
||||||
|
SVGSVGBox <svg> at (8,8) content-size 300x150 [SVG] children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
Box <use> at (8,8) content-size 0x0 children: inline
|
||||||
|
Box <symbol#braces> at (8,8) content-size 0x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
SVGGeometryBox <path> at (92.375,26.75) content-size 131.25x112.15625 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x150]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0]
|
||||||
|
PaintableWithLines (BlockContainer<DIV>) [8,8 784x150]
|
||||||
|
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 300x150]
|
||||||
|
PaintableBox (Box<use>) [8,8 0x0]
|
||||||
|
PaintableBox (Box<symbol>#braces) [8,8 0x0]
|
||||||
|
SVGGeometryPaintable (SVGGeometryBox<path>) [92.375,26.75 131.25x112.15625]
|
||||||
|
|
||||||
|
)"sv;
|
||||||
|
|
||||||
|
StringView new_text = R"(Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x150 children: not-inline
|
||||||
|
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <div> at (8,8) content-size 784x150 children: inline
|
||||||
|
line 0 width: 300, height: 150, bottom: 150, baseline: 150
|
||||||
|
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 300x150]
|
||||||
|
TextNode <#text>
|
||||||
|
SVGSVGBox <svg> at (8,8) content-size 300x150 [SVG] children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
Box <use> at (8,8) content-size 0x0 children: not-inline
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x150]
|
||||||
|
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0]
|
||||||
|
PaintableWithLines (BlockContainer<DIV>) [8,8 784x150]
|
||||||
|
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 300x150]
|
||||||
|
PaintableBox (Box<use>) [8,8 0x0]
|
||||||
|
|
||||||
|
)"sv;
|
||||||
|
|
||||||
|
auto result = MUST(Diff::from_text(old_text, new_text, 3));
|
||||||
|
EXPECT_EQ(result.size(), 2U);
|
||||||
|
|
||||||
|
auto hunk1_stream = make<AllocatingMemoryStream>();
|
||||||
|
MUST(Diff::write_unified(result[0], *hunk1_stream));
|
||||||
|
|
||||||
|
auto hunk1 = MUST(hunk1_stream->read_until_eof());
|
||||||
|
EXPECT_EQ(StringView { hunk1 }, R"(@@ -10,12 +10,7 @@
|
||||||
|
TextNode <#text>
|
||||||
|
SVGSVGBox <svg> at (8,8) content-size 300x150 [SVG] children: inline
|
||||||
|
TextNode <#text>
|
||||||
|
- Box <use> at (8,8) content-size 0x0 children: inline
|
||||||
|
- Box <symbol#braces> at (8,8) content-size 0x0 children: inline
|
||||||
|
- TextNode <#text>
|
||||||
|
- SVGGeometryBox <path> at (92.375,26.75) content-size 131.25x112.15625 children: inline
|
||||||
|
- TextNode <#text>
|
||||||
|
- TextNode <#text>
|
||||||
|
+ Box <use> at (8,8) content-size 0x0 children: not-inline
|
||||||
|
TextNode <#text>
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
)"sv);
|
||||||
|
|
||||||
|
auto hunk2_stream = make<AllocatingMemoryStream>();
|
||||||
|
MUST(Diff::write_unified(result[1], *hunk2_stream));
|
||||||
|
|
||||||
|
auto hunk2 = MUST(hunk2_stream->read_until_eof());
|
||||||
|
EXPECT_EQ(StringView { hunk2 }, R"(@@ -26,6 +21,4 @@
|
||||||
|
PaintableWithLines (BlockContainer<DIV>) [8,8 784x150]
|
||||||
|
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 300x150]
|
||||||
|
PaintableBox (Box<use>) [8,8 0x0]
|
||||||
|
- PaintableBox (Box<symbol>#braces) [8,8 0x0]
|
||||||
|
- SVGGeometryPaintable (SVGGeometryBox<path>) [92.375,26.75 131.25x112.15625]
|
||||||
|
|
||||||
|
)"sv);
|
||||||
|
}
|
|
@ -90,7 +90,7 @@ ErrorOr<Vector<Hunk>> from_text(StringView old_text, StringView new_text, size_t
|
||||||
|
|
||||||
for (size_t offset = 0; offset < available_context; ++offset) {
|
for (size_t offset = 0; offset < available_context; ++offset) {
|
||||||
size_t context_line = i + offset - available_context;
|
size_t context_line = i + offset - available_context;
|
||||||
TRY(hunk.lines.try_append(Line { Line::Operation::Context, TRY(String::from_utf8(new_lines[context_line])) }));
|
TRY(hunk.lines.try_append(Line { Line::Operation::Context, TRY(String::from_utf8(old_lines[context_line])) }));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
Loading…
Reference in a new issue