Skip to content

Commit 10f1d3d

Browse files
authored
Fix potential corrupt extracts when canceled (#267)
* Fix potential corrupt extracts when canceled * write the header at the very end of the extract function instead of at the beginning. * more error handling
1 parent e22c5b2 commit 10f1d3d

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

pmtiles/extract.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,9 +462,10 @@ func Extract(ctx context.Context, logger *log.Logger, bucketURL string, key stri
462462
return err
463463
}
464464

465-
outfile.Truncate(127 + int64(len(newRootBytes)) + int64(header.MetadataLength) + int64(len(newLeavesBytes)) + int64(totalActualBytes))
466-
467-
_, err = outfile.Write(headerBytes)
465+
// set the file size and write empty space for the header for now
466+
// see comment below
467+
outfile.Truncate(HeaderV3LenBytes + int64(len(newRootBytes)) + int64(header.MetadataLength) + int64(len(newLeavesBytes)) + int64(totalActualBytes))
468+
_, err = outfile.Write(make([]byte, HeaderV3LenBytes))
468469
if err != nil {
469470
return err
470471
}
@@ -486,7 +487,10 @@ func Extract(ctx context.Context, logger *log.Logger, bucketURL string, key stri
486487
return err
487488
}
488489

489-
outfile.Write(metadataBytes)
490+
_, err = outfile.Write(metadataBytes)
491+
if err != nil {
492+
return err
493+
}
490494

491495
// 10. write the leaf directories
492496
_, err = outfile.Write(newLeavesBytes)
@@ -559,6 +563,16 @@ func Extract(ctx context.Context, logger *log.Logger, bucketURL string, key stri
559563
if err != nil {
560564
return err
561565
}
566+
567+
// Write the header when finishing,
568+
// otherwise a extract cancelled during the tile download section
569+
// will appear valid with "pmtiles verify"
570+
// even though the tile contents are corrupted.
571+
outfile.Seek(0, io.SeekStart)
572+
_, err = outfile.Write(headerBytes)
573+
if err != nil {
574+
return err
575+
}
562576
}
563577

564578
logger.Printf("Completed in %v with %v download threads (%v tiles/s).\n", time.Since(start), downloadThreads, float64(len(reencoded))/float64(time.Since(start).Seconds()))

0 commit comments

Comments
 (0)