@@ -145,8 +145,23 @@ bool MCBlock::visit(MCObjectVisitorOptions p_options, uint32_t p_part, MCObjectV
145145 return p_visitor -> OnBlock (this );
146146}
147147
148+ // IM-2016-07-06: [[ Bug 17690 ]] Test if block sizes or offsets require 32bit
149+ // values to store (stack file format v8.1).
148150uint32_t MCBlock::getminimumstackfileversion (void )
149151{
152+ bool t_is_unicode;
153+ // paragraph text is always unicode when saving as version 7.0 or greater.
154+ // since we can't know which version will be used at this point, the
155+ // best we can do is assume unicode text.
156+ /* t_is_unicode = !MCStringIsNative(parent->GetInternalStringRef()); */
157+ t_is_unicode = true ;
158+
159+ uint32_t t_index_size;
160+ t_index_size = t_is_unicode ? sizeof (unichar_t ) : sizeof (char_t );
161+
162+ if (m_index * t_index_size > UINT16_MAX || m_size * t_index_size > UINT16_MAX)
163+ return kMCStackFileFormatVersion_8_1 ;
164+ else
150165 return kMCStackFileFormatMinimumExportVersion ;
151166}
152167
@@ -310,13 +325,33 @@ IO_stat MCBlock::load(IO_handle stream, uint32_t version, bool is_ext)
310325 //
311326 // Helpfully, the paragraph loading code makes a SetRanges call to inform
312327 // the block of the correct offsets as soon as it knows them.
313- uint2 index, size;
314- if ((stat = IO_read_uint2 (&index, stream)) != IO_NORMAL)
315- return checkloadstat (stat);
316- if ((stat = IO_read_uint2 (&size, stream)) != IO_NORMAL)
317- return checkloadstat (stat);
318- m_index = index;
319- m_size = size;
328+
329+ // IM-2016-07-11: [[ Bug 17690 ]] change storage format for index & size from
330+ // 16bit to 32bit in stack file format v8.1.
331+ if (version >= kMCStackFileFormatVersion_8_1 )
332+ {
333+ uint32_t t_index, t_size;
334+ stat = IO_read_uint4 (&t_index, stream);
335+ if (stat != IO_NORMAL)
336+ return checkloadstat (stat);
337+
338+ stat = IO_read_uint4 (&t_size, stream);
339+ if (stat != IO_NORMAL)
340+ return checkloadstat (stat);
341+
342+ m_index = t_index;
343+ m_size = t_size;
344+ }
345+ else
346+ {
347+ uint2 index, size;
348+ if ((stat = IO_read_uint2 (&index, stream)) != IO_NORMAL)
349+ return checkloadstat (stat);
350+ if ((stat = IO_read_uint2 (&size, stream)) != IO_NORMAL)
351+ return checkloadstat (stat);
352+ m_index = index;
353+ m_size = size;
354+ }
320355
321356 // MW-2012-02-17: [[ SplitTextAttrs ]] Adjust the flags to their in-memory
322357 // representation. We ditch F_FONT because it is superceeded by the HAS_F*
@@ -465,10 +500,25 @@ IO_stat MCBlock::save(IO_handle stream, uint4 p_part, uint32_t p_version)
465500 uint32_t t_index_size;
466501 t_index_size = t_is_unicode ? sizeof (unichar_t ) : sizeof (char_t );
467502
468- if ((stat = IO_write_uint2 (m_index * t_index_size, stream)) != IO_NORMAL)
469- return stat;
470- if ((stat = IO_write_uint2 (m_size * t_index_size, stream)) != IO_NORMAL)
471- return stat;
503+ // IM-2016-07-11: [[ Bug 17690 ]] change storage format for index & size from
504+ // 16bit to 32bit in stack file format v8.1.
505+ if (p_version >= kMCStackFileFormatVersion_8_1 )
506+ {
507+ stat = IO_write_uint4 (m_index * t_index_size, stream);
508+ if (stat != IO_NORMAL)
509+ return checkloadstat (stat);
510+
511+ stat = IO_write_uint4 (m_size * t_index_size, stream);
512+ if (stat != IO_NORMAL)
513+ return checkloadstat (stat);
514+ }
515+ else
516+ {
517+ if ((stat = IO_write_uint2 (m_index * t_index_size, stream)) != IO_NORMAL)
518+ return stat;
519+ if ((stat = IO_write_uint2 (m_size * t_index_size, stream)) != IO_NORMAL)
520+ return stat;
521+ }
472522
473523 return IO_NORMAL;
474524}
0 commit comments