From c74fa6cd54180b7c0959283dd2b6f059177c4cfd Mon Sep 17 00:00:00 2001 From: Alcaro Date: Fri, 23 Dec 2016 14:43:22 +0100 Subject: [PATCH] Add BPS/UPS tests, fix bugs --- patch/bps-create.cpp | 13 +++++-- patch/test.cpp | 80 +++++++++++++++++++++++++------------------- patch/ups.cpp | 17 +++++++--- 3 files changed, 67 insertions(+), 43 deletions(-) diff --git a/patch/bps-create.cpp b/patch/bps-create.cpp index 444fda3..6c66cf6 100644 --- a/patch/bps-create.cpp +++ b/patch/bps-create.cpp @@ -223,14 +223,17 @@ struct bps_creator { outpos = 0; + sourcelen = source.size(); + targetlen = target.size(); + sourcecopypos = 0; targetcopypos = 0; numtargetread = 0; append((const uint8_t*)"BPS1", 4); - appendnum(source.size()); - appendnum(target.size()); + appendnum(sourcelen); + appendnum(targetlen); appendnum(metadata.len); append(metadata.ptr, metadata.len); } @@ -719,6 +722,9 @@ static result create_suf_core(const file& source, const file& target, struct bps if (target.read(arrayvieww(mem_joined, sortedsize), 0) < (size_t)sortedsize) error(e_io); if (source.read(arrayvieww(mem_joined+sortedsize, sourcelen), 0) < (size_t)sourcelen) error(e_io); out->move_target(mem_joined); + + if (targetlen==0) goto emitempty; // size-0 targets are silly, but have to be handled + sufsort(sorted, mem_joined, sortedsize+sourcelen); if (out->progress(progPreBuck, targetlen)) error(e_canceled); @@ -749,6 +755,7 @@ static result create_suf_core(const file& source, const file& target, struct bps #endif outpos += taken; } +emitempty: out->finish(mem_joined+sortedsize, mem_joined); @@ -793,9 +800,9 @@ result create(const file& source, const file& target, const file& metadata, file mem patchmem = bps.getpatch(); patch.write(patchmem.v()); - free(patchmem.ptr); while ((patchmem.ptr[maindata]&0x80) == 0x00) maindata++; + free(patchmem.ptr); if (maindata==patchmem.len-12-1) return e_identical; return e_ok; } diff --git a/patch/test.cpp b/patch/test.cpp index 239c0d5..e795893 100644 --- a/patch/test.cpp +++ b/patch/test.cpp @@ -60,34 +60,41 @@ static void createtest(arrayview a, arrayview b, size_t ipssize, siz if (testips && b.size()<=16777216) { array patch; - ips::create(file::mem(a), file::mem(b), file::mem(patch)); // don't worry about return value + result r = ips::create(file::mem(a), file::mem(b), file::mem(patch)); + if (r!=e_identical) assert_eq(r, e_ok); array b2; - result r = ips::apply(file::mem(patch), file::mem(a), file::mem(b2)); + r = ips::apply(file::mem(patch), file::mem(a), file::mem(b2)); if (r!=e_to_output) assert_eq(r, e_ok); assert_eq(b2.size(), b.size()); for (size_t i=0;i patch; - bps::create(file::mem(a), file::mem(b), file::mem(patch), NULL); // don't worry about return value + result r = bps::create(file::mem(a), file::mem(b), file::mem(patch), NULL); + if (r!=e_identical) assert_eq(r, e_ok); array b2; - bps::apply(file::mem(patch), file::mem(a), file::mem(b2)); + r = bps::apply(file::mem(patch), file::mem(a), file::mem(b2)); + if (r!=e_to_output) assert_eq(r, e_ok); assert_eq(b2.size(), b.size()); for (size_t i=0;i seq256b5; for (int i=0;i<256;i++) seq256b5[i]=i; seq256b5[255+5]=1; array seq256b6; for (int i=0;i<256;i++) seq256b6[i]=i; seq256b6[255+6]=1; array seq256b7; for (int i=0;i<256;i++) seq256b7[i]=i; seq256b7[255+7]=1; - array eof; eof[0x454F46] = 1; + array eof1; eof1[0x454F46] = 1; array eof2; for (int i=0;i<16;i++) eof2[0x454F46+i] = 1; array eof3; eof3[0x454F46] = 0; array eof4; eof4[0x454F45] = 2; eof4[0x454F46] = 1; @@ -117,23 +124,29 @@ static void simpletests() int record = 3+2; // offset, len int rle = 3+2+2+1; // offset, len=0, rlelen, byte int trunc = 3; - testcall(createtest(empty, empty, base, 0)); - testcall(createtest(empty, one1, base+record+1, 0)); - testcall(createtest(one1, empty, base+trunc, 0)); - testcall(createtest(one0, one1, base+record+1, 0)); - testcall(createtest(seq256, seq128, base+trunc, 0)); - testcall(createtest(seq128, seq256, base+record+128, 0)); - testcall(createtest(empty, seq256nul4, base+record+255+4, 0)); - testcall(createtest(empty, seq256nul5, base+record+255+5, 0)); - testcall(createtest(empty, seq256nul6, base+record+255+6, 0)); - testcall(createtest(empty, seq256nul7, base+record+255+record+1, 0)); - testcall(createtest(empty, seq256b4, base+record+255+4, 0)); - testcall(createtest(empty, seq256b5, base+record+255+5, 0)); - testcall(createtest(empty, seq256b6, base+record+255+6, 0)); - testcall(createtest(empty, seq256b7, base+record+255+record+1, 0)); - testcall(createtest(empty, eof, base+record+2, 0)); - testcall(createtest(empty, eof2, base+record+2+rle, 0)); - testcall(createtest(empty, eof3, base+record+2, 0)); + testcall(createtest(empty, empty, base, 19)); + testcall(createtest(empty, one1, base+record+1, 21)); + testcall(createtest(one1, empty, base+trunc, 19)); + testcall(createtest(one0, one1, base+record+1, 21)); + testcall(createtest(seq256, seq128, base+trunc, 23)); + testcall(createtest(seq128, seq256, base+record+128, 153)); + testcall(createtest(empty, seq256nul4, base+record+255+4, 282)); + testcall(createtest(empty, seq256nul5, base+record+255+5, 283)); + testcall(createtest(empty, seq256nul6, base+record+255+6, 282)); + testcall(createtest(empty, seq256nul7, base+record+255+record+1, 282)); + testcall(createtest(empty, seq256b4, base+record+255+4, 282)); + testcall(createtest(empty, seq256b5, base+record+255+5, 283)); + testcall(createtest(empty, seq256b6, base+record+255+6, 284)); + testcall(createtest(empty, seq256b7, base+record+255+record+1, 284)); + testcall(createtest(empty, eof1, base+record+2, 57)); + //if (testips) // don't need these for BPS, 0x454F46 isn't significant there + { // one's enough, for testing large files + testcall(createtest(empty, eof2, base+record+2+rle, 59)); + testcall(createtest(empty, eof3, base+record+2, 55)); + testcall(createtest(empty, eof4, base+record+2, 58)); + testcall(createtest(empty, eof5, base+record+2+rle, 60)); + testcall(createtest(empty, eof6, base+record+2, 58)); + } } test("IPS") @@ -146,8 +159,6 @@ test("IPS") test("BPS") { - //test_skip("fix ips first"); - testips=false; testbps=true; @@ -159,8 +170,6 @@ test("the big ones") testips=true; testbps=true; - test_skip("enable this whenever ips/bps tests are done (also this is sufficient ups test)"); - array smw = file::read("patch/test/smw.sfc"); array smw_bps = file::read("patch/test/smwcp.bps"); array dl = file::read("patch/test/langrisser.sfc"); @@ -171,14 +180,15 @@ test("the big ones") array smwhack; bps::apply(file::mem(smw_bps), file::mem(smw), file::mem(smwhack)); - testcall(createtest(smw, smwhack, 3328022, 2077386)); + testcall(createtest(smw, smwhack, 3302980, 2077386)); array sm64hack; bps::apply(file::mem(sm64_bps), file::mem(sm64), file::mem(sm64hack)); - testcall(createtest(sm64, sm64hack, -1, 0)); + testcall(createtest(sm64, sm64hack, -1, 6788133)); + //this is the only UPS test, UPS is pretty much an easter egg in Flips array dlhack; ups::apply(file::mem(dl_ups), file::mem(dl), file::mem(dlhack)); - testcall(createtest(dl, dlhack, 0, 0)); + testcall(createtest(dl, dlhack, 852134, 817190)); } } diff --git a/patch/ups.cpp b/patch/ups.cpp index 01a419c..afd50dc 100644 --- a/patch/ups.cpp +++ b/patch/ups.cpp @@ -19,8 +19,8 @@ result apply(const file& patch_, const file& source_, file& target_) { if (patch_.size()<4+2+12) return e_broken; - struct mem patch = patch_.read(); - struct mem in = source_.read(); + struct mem patch = patch_.mmap(); + struct mem in = source_.mmap(); struct mem out_; struct mem * out = &out_; result error; @@ -123,7 +123,11 @@ result apply(const file& patch_, const file& source_, file& target_) if (inlen==outlen) { - if ((crc_in!=crc_in_expected || crc_out!=crc_out_expected) && (crc_in!=crc_out_expected || crc_out!=crc_in_expected)) error(e_not_this); + if ((crc_in!=crc_in_expected || crc_out!=crc_out_expected) && + (crc_in!=crc_out_expected || crc_out!=crc_in_expected)) + { + error(e_not_this); + } } else { @@ -142,7 +146,8 @@ result apply(const file& patch_, const file& source_, file& target_) target_.write(out->v()); free(out->ptr); - free(patch.ptr); + patch_.unmap(patch.v()); + source_.unmap(in.v()); return e_ok; #undef read8 #undef decodeto @@ -150,8 +155,10 @@ result apply(const file& patch_, const file& source_, file& target_) } exit: - free(patch.ptr); + free(out->ptr); + patch_.unmap(patch.v()); + source_.unmap(in.v()); out->len=0; out->ptr=NULL; return error;