@@ -140,14 +140,21 @@ auto bzlreg::tar_view::iterator::operator++() -> iterator& {
140140 assert (!_data.empty ());
141141 auto file_size = operator *().size ();
142142 auto header_size = operator *().header_byte_size ();
143- _data = _data.subspan (header_size + round_up_to_multiple (file_size, 512 ));
144- if (is_all0 (_data.subspan (0 , TAR_HEADER_SIZE))) {
145- _data = _data.subspan (TAR_HEADER_SIZE);
143+ auto file_size_rounded = round_up_to_multiple (file_size, 512 );
146144
145+ if (header_size + file_size_rounded < _data.size ()) {
146+ _data = _data.subspan (header_size + file_size_rounded);
147147 if (is_all0 (_data.subspan (0 , TAR_HEADER_SIZE))) {
148- _data = {};
148+ _data = _data.subspan (TAR_HEADER_SIZE);
149+
150+ if (is_all0 (_data.subspan (0 , TAR_HEADER_SIZE))) {
151+ _data = {};
152+ }
149153 }
154+ } else {
155+ _data = {};
150156 }
157+
151158 return *this ;
152159}
153160
@@ -236,12 +243,12 @@ bzlreg::tar_view_file::tar_view_file( //
236243 }
237244
238245 auto key = extended_header.substr (
239- length_sep_index,
240- key_value_sep_index - length_sep_index
246+ length_sep_index + 1 ,
247+ key_value_sep_index - length_sep_index - 1
241248 );
242249 auto value = extended_header.substr (
243- key_value_sep_index,
244- length - (length_sep_index - key. size () - 2 )
250+ key_value_sep_index + 1 ,
251+ length - key_value_sep_index - 2
245252 );
246253
247254 auto value_span = std::span{
@@ -256,6 +263,8 @@ bzlreg::tar_view_file::tar_view_file( //
256263 } else if (key == " size" ) {
257264 _extended_header_size = value_span;
258265 }
266+
267+ extended_header = extended_header.substr (length);
259268 }
260269 }
261270}
@@ -274,7 +283,8 @@ auto bzlreg::tar_view_file::header_byte_size() const -> size_t {
274283
275284 if (typeflag == typeflag_enum::extended_header) {
276285 return TAR_HEADER_SIZE +
277- round_up_to_multiple (get_tar_header_file_size (_data), 512 );
286+ round_up_to_multiple (get_tar_header_file_size (_data), 512 ) +
287+ TAR_HEADER_SIZE;
278288 } else {
279289 return TAR_HEADER_SIZE;
280290 }
@@ -325,25 +335,44 @@ auto bzlreg::tar_view_file::size() const noexcept -> size_t {
325335 assert (*this );
326336
327337 const auto typeflag = get_typeflag (_data);
338+ auto file_size = std::size_t {};
328339
329340 if (typeflag == typeflag_enum::extended_header) {
330- auto file_size = std::size_t {};
331- auto [_, ec] = std::from_chars (
332- reinterpret_cast <const char *>(_extended_header_size.data ()),
333- reinterpret_cast <const char *>(_extended_header_size.data ()) +
334- _extended_header_size.size (),
335- file_size
336- );
337- if (ec != std::errc{}) {
338- std::cerr << " ERROR: extended header file size: "
339- << std::make_error_code (ec).message () << std::endl;
340- std::abort ();
341+ if (!_extended_header_size.empty ()) {
342+ auto [_, ec] = std::from_chars (
343+ reinterpret_cast <const char *>(_extended_header_size.data ()),
344+ reinterpret_cast <const char *>(_extended_header_size.data ()) +
345+ _extended_header_size.size (),
346+ file_size
347+ );
348+ if (ec != std::errc{}) {
349+ std::cerr << " ERROR: extended header file size: "
350+ << std::make_error_code (ec).message () << std::endl;
351+ std::abort ();
352+ }
353+ } else {
354+ auto next_entry = _data.subspan (
355+ TAR_HEADER_SIZE +
356+ round_up_to_multiple (get_tar_header_file_size (_data), 512 )
357+ );
358+ auto next_typeflag = get_typeflag (next_entry);
359+ switch (next_typeflag) {
360+ case typeflag_enum::extended_header:
361+ case typeflag_enum::global_extended_header:
362+ std::cerr << " ERROR: unexpected typeflag: "
363+ << static_cast <char >(next_typeflag) << " \n " ;
364+ std::abort ();
365+ break ;
366+ default :
367+ break ;
368+ }
369+ file_size = get_tar_header_file_size (next_entry);
341370 }
342-
343- return file_size;
344371 } else {
345- return get_tar_header_file_size (_data);
372+ file_size = get_tar_header_file_size (_data);
346373 }
374+
375+ return file_size;
347376}
348377
349378auto bzlreg::tar_view_file::contents () const noexcept -> std::span<std::byte> {
0 commit comments