Skip to content

Commit 9c46a47

Browse files
committed
maint: Merge stable to default.
2 parents 5c76914 + e26f65a commit 9c46a47

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

libinterp/corefcn/ls-oct-binary.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,28 @@ save_binary_data (std::ostream& os, const octave_value& tc,
341341
const std::string& name, const std::string& doc,
342342
bool mark_global, bool save_as_floats)
343343
{
344+
static octave_idx_type max_dim_val = std::numeric_limits<int32_t>::max () - 1;
345+
346+
dim_vector dv = tc.dims ();
347+
if (dv.ndims () > max_dim_val)
348+
{
349+
warning_with_id ("Octave:save:dimension-too-large",
350+
"save: skipping %s: number of dimensions too large for binary format",
351+
name.c_str ());
352+
return true;
353+
}
354+
355+
for (octave_idx_type i_dim = 0; i_dim < dv.ndims (); i_dim++)
356+
{
357+
if (dv(i_dim) > max_dim_val)
358+
{
359+
warning_with_id ("Octave:save:dimension-too-large",
360+
"save: skipping %s: dimensions too large for binary format",
361+
name.c_str ());
362+
return true;
363+
}
364+
}
365+
344366
int32_t name_len = name.length ();
345367

346368
os.write (reinterpret_cast<char *> (&name_len), 4);

liboctave/util/data-conv.cc

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,9 @@ oct_data_conv::data_type_as_string (oct_data_conv::data_type dt)
610610
{ \
611611
OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
612612
std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
613-
stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
613+
do_read (stream, reinterpret_cast<char *> (ptr), n_bytes); \
614+
if (! stream) \
615+
return; \
614616
if (swap) \
615617
swap_bytes< size > (ptr, len); \
616618
for (octave_idx_type i = 0; i < len; i++) \
@@ -633,7 +635,7 @@ oct_data_conv::data_type_as_string (oct_data_conv::data_type dt)
633635
for (octave_idx_type i = 0; i < len; i++) \
634636
ptr[i] = static_cast<TYPE> (data[i]); \
635637
std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
636-
stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
638+
do_write (stream, reinterpret_cast<const char *> (ptr), n_bytes); \
637639
} \
638640
} \
639641
while (0)
@@ -798,6 +800,22 @@ do_float_format_conversion (void *data, std::size_t sz, octave_idx_type len,
798800
}
799801
}
800802

803+
static void
804+
do_read (std::istream& is, char *byte_data, std::streamsize n_bytes)
805+
{
806+
// read large data in chunks of 64 MiB
807+
constexpr std::streamsize chunk_size = 64 * 1024 * 1024;
808+
for (std::streamsize offset = 0; offset < n_bytes; )
809+
{
810+
std::streamsize to_read = std::min (chunk_size, n_bytes - offset);
811+
is.read (byte_data + offset, to_read);
812+
813+
if (! is)
814+
return;
815+
816+
offset += to_read;
817+
}
818+
}
801819
void
802820
read_doubles (std::istream& is, double *data, save_type type,
803821
octave_idx_type len, bool swap,
@@ -832,8 +850,10 @@ read_doubles (std::istream& is, double *data, save_type type,
832850
case LS_FLOAT:
833851
{
834852
OCTAVE_LOCAL_BUFFER (float, ptr, len);
835-
std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
836-
is.read (reinterpret_cast<char *> (ptr), n_bytes);
853+
std::streamsize n_bytes = sizeof (float) * static_cast<std::streamsize> (len);
854+
do_read (is, reinterpret_cast<char *> (data), n_bytes);
855+
if (! is)
856+
return;
837857
do_float_format_conversion (ptr, len, fmt);
838858
for (octave_idx_type i = 0; i < len; i++)
839859
data[i] = ptr[i];
@@ -842,8 +862,10 @@ read_doubles (std::istream& is, double *data, save_type type,
842862

843863
case LS_DOUBLE: // No conversion necessary.
844864
{
845-
std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
846-
is.read (reinterpret_cast<char *> (data), n_bytes);
865+
std::streamsize n_bytes = sizeof (double) * static_cast<std::streamsize> (len);
866+
do_read (is, reinterpret_cast<char *> (data), n_bytes);
867+
if (! is)
868+
return;
847869
do_double_format_conversion (data, len, fmt);
848870
// FIXME: Potentially add conversion code for MIPS NA here, Bug #59830.
849871
//
@@ -891,8 +913,10 @@ read_floats (std::istream& is, float *data, save_type type,
891913

892914
case LS_FLOAT: // No conversion necessary.
893915
{
894-
std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
895-
is.read (reinterpret_cast<char *> (data), n_bytes);
916+
std::streamsize n_bytes = sizeof (float) * static_cast<std::streamsize> (len);
917+
do_read (is, reinterpret_cast<char *> (data), n_bytes);
918+
if (! is)
919+
return;
896920
do_float_format_conversion (data, len, fmt);
897921
}
898922
break;
@@ -901,7 +925,9 @@ read_floats (std::istream& is, float *data, save_type type,
901925
{
902926
OCTAVE_LOCAL_BUFFER (double, ptr, len);
903927
std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
904-
is.read (reinterpret_cast<char *> (ptr), n_bytes);
928+
do_read (is, reinterpret_cast<char *> (data), n_bytes);
929+
if (! is)
930+
return;
905931
do_double_format_conversion (ptr, len, fmt);
906932
for (octave_idx_type i = 0; i < len; i++)
907933
data[i] = ptr[i];
@@ -914,6 +940,22 @@ read_floats (std::istream& is, float *data, save_type type,
914940
}
915941
}
916942

943+
static void
944+
do_write (std::ostream& os, const char *byte_data, std::streamsize n_bytes)
945+
{
946+
// write large data in chunks of 64 MiB
947+
constexpr std::streamsize chunk_size = 64 * 1024 * 1024;
948+
for (std::streamsize written = 0; written < n_bytes; )
949+
{
950+
std::streamsize remaining = n_bytes - written;
951+
std::streamsize to_write = std::min (chunk_size, remaining);
952+
os.write (byte_data + written, to_write);
953+
if (! os)
954+
return;
955+
written += to_write;
956+
}
957+
}
958+
917959
void
918960
write_doubles (std::ostream& os, const double *data, save_type type,
919961
octave_idx_type len)
@@ -952,8 +994,9 @@ write_doubles (std::ostream& os, const double *data, save_type type,
952994
{
953995
char tmp_type = static_cast<char> (type);
954996
os.write (&tmp_type, 1);
955-
std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
956-
os.write (reinterpret_cast<const char *> (data), n_bytes);
997+
998+
std::streamsize n_bytes = sizeof (double) * static_cast<std::streamsize> (len);
999+
do_write (os, reinterpret_cast<const char *> (data), n_bytes);
9571000
}
9581001
break;
9591002

@@ -998,8 +1041,8 @@ write_floats (std::ostream& os, const float *data, save_type type,
9981041
{
9991042
char tmp_type = static_cast<char> (type);
10001043
os.write (&tmp_type, 1);
1001-
std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
1002-
os.write (reinterpret_cast<const char *> (data), n_bytes);
1044+
std::streamsize n_bytes = sizeof (float) * static_cast<std::streamsize> (len);
1045+
do_write (os, reinterpret_cast<const char *> (data), n_bytes);
10031046
}
10041047
break;
10051048

0 commit comments

Comments
 (0)