@@ -72,20 +72,6 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
7272
7373MCImage *MCDispatch::imagecache;
7474
75- #define VERSION_OFFSET 11
76-
77- #define HEADERSIZE 255
78- static char header[HEADERSIZE ] = " #!/bin/sh\n # MetaCard 2.4 stack\n # The following is not ASCII text,\n # so now would be a good time to q out of more\f\n exec mc $0 \" $@\"\n " ;
79-
80- #define NEWHEADERSIZE 8
81- #define HEADERPREFIXSIZE 4
82- static const char *newheader = " REVO2700" ;
83- static const char *newheader5500 = " REVO5500" ;
84- static const char *newheader7000 = " REVO7000" ;
85- static const char *newheader8000 = " REVO8000" ;
86-
87- #define MAX_STACKFILE_VERSION 8000
88-
8975// //////////////////////////////////////////////////////////////////////////////
9076
9177MCPropertyInfo MCDispatch::kProperties [] =
@@ -431,66 +417,33 @@ Boolean MCDispatch::openenv(MCStringRef sname, MCStringRef env,
431417
432418IO_stat readheader (IO_handle& stream, uint32_t & r_version)
433419{
434- char tnewheader[NEWHEADERSIZE ];
435- if (IO_read (tnewheader, NEWHEADERSIZE , stream) == IO_NORMAL )
436- {
437- // AL-2014-10-27: [[ Bug 12558 ]] Check for valid header prefix
438- if (strncmp (tnewheader, " REVO" , HEADERPREFIXSIZE ) == 0 )
439- {
440- // The header version can now consist of any alphanumeric characters
441- // They map to numbers as follows:
442- // 0-9 -> 0-9
443- // A-Z -> 10-35
444- // a-z -> 36-61
445- uint1 versionnum[4 ];
446- for (uint1 i = 0 ; i < 4 ; i++)
447- {
448- char t_char = tnewheader[i + 4 ];
449- if (' 0' <= t_char && t_char <= ' 9' )
450- versionnum[i] = (uint1)(t_char - ' 0' );
451- else if (' A' <= t_char && t_char <= ' Z' )
452- versionnum[i] = (uint1)(t_char - ' A' + 10 );
453- else if (' a' <= t_char && t_char <= ' z' )
454- versionnum[i] = (uint1)(t_char - ' a' + 36 );
455- else
456- return IO_ERROR ;
457- }
458-
459- // Future file format versions will always still compare greater than MAX_STACKFILE_VERSION,
460- // so it is ok that r_version does not accurately reflect future version values.
461- // TODO: change this, and comparisons for version >= 7000 / 5500, etc
462- r_version = versionnum[0 ] * 1000 ;
463- r_version += versionnum[1 ] * 100 ;
464- r_version += versionnum[2 ] * 10 ;
465- r_version += versionnum[3 ];
466- }
467- else
420+ char tnewheader[kMCStackFileVersionStringLength ];
421+ if (IO_read (tnewheader, kMCStackFileVersionStringLength , stream) != IO_NORMAL )
422+ return IO_ERROR ;
423+
424+ // AL-2014-10-27: [[ Bug 12558 ]] Check for valid header prefix
425+ if (!MCStackFileParseVersionNumber (tnewheader, r_version))
426+ {
427+ char theader[kMCStackFileMetaCardVersionStringLength + 1 ];
428+ theader[kMCStackFileMetaCardVersionStringLength ] = ' \0 ' ;
429+ uint4 offset;
430+ strncpy (theader, tnewheader, kMCStackFileVersionStringLength );
431+ if (IO_read (theader + kMCStackFileVersionStringLength , kMCStackFileMetaCardVersionStringLength - kMCStackFileVersionStringLength , stream) == IO_NORMAL
432+ && MCU_offset (kMCStackFileMetaCardSignature , theader, offset))
468433 {
469- char theader[HEADERSIZE + 1 ];
470- theader[HEADERSIZE ] = ' \0 ' ;
471- uint4 offset;
472- strncpy (theader, tnewheader, NEWHEADERSIZE );
473- if (IO_read (theader + NEWHEADERSIZE , HEADERSIZE - NEWHEADERSIZE , stream) == IO_NORMAL
474- && MCU_offset (SIGNATURE , theader, offset))
434+ if (theader[offset - 1 ] != ' \n ' || theader[offset - 2 ] == ' \r ' )
475435 {
476- if (theader[offset - 1 ] != ' \n ' || theader[offset - 2 ] == ' \r ' )
477- {
478- MCresult->sets (" stack was corrupted by a non-binary file transfer" );
479- return IO_ERROR ;
480- }
481-
482- r_version = (theader[offset + VERSION_OFFSET ] - ' 0' ) * 1000 ;
483- r_version += (theader[offset + VERSION_OFFSET + 2 ] - ' 0' ) * 100 ;
484- }
485- else
436+ MCresult->sets (" stack was corrupted by a non-binary file transfer" );
486437 return IO_ERROR ;
438+ }
439+
440+ r_version = (theader[offset + kMCStackFileMetaCardSignatureLength ] - ' 0' ) * 1000 ;
441+ r_version += (theader[offset + kMCStackFileMetaCardSignatureLength + 2 ] - ' 0' ) * 100 ;
487442 }
443+ else
444+ return IO_ERROR ;
488445 }
489- else
490- {
491- // Could not read header
492- return IO_ERROR ;
493- }
446+
494447 return IO_NORMAL ;
495448}
496449
@@ -597,7 +550,7 @@ IO_stat MCDispatch::doreadfile(MCStringRef p_openpath, MCStringRef p_name, IO_ha
597550 // MW-2014-09-30: [[ ScriptOnlyStack ]] First see if it is a binary stack.
598551 if (readheader (stream, version) == IO_NORMAL )
599552 {
600- if (version > MAX_STACKFILE_VERSION )
553+ if (version > kMCStackFileFormatCurrentVersion )
601554 {
602555 MCresult->sets (" stack was produced by a newer version" );
603556 return checkloadstat (IO_ERROR );
@@ -995,7 +948,7 @@ IO_stat MCDispatch::savestack(MCStack *sptr, const MCStringRef p_fname, uint32_t
995948 }
996949 else
997950 {
998- /* If no version was specified, assume that 8.0 format was requested */
951+ /* If no version was specified, assume that current format was requested */
999952 if (UINT32_MAX == p_version)
1000953 {
1001954 p_version = kMCStackFileFormatCurrentVersion ;
@@ -1148,16 +1101,7 @@ IO_stat MCDispatch::dosavestack(MCStack *sptr, const MCStringRef p_fname, uint32
11481101 // MW-2012-03-04: [[ StackFile5500 ]] Work out what header to emit, and the size.
11491102 const char *t_header;
11501103 uint32_t t_header_size;
1151- if (p_version >= kMCStackFileFormatVersion_8_0 )
1152- t_header = newheader8000, t_header_size = 8 ;
1153- else if (p_version >= kMCStackFileFormatVersion_7_0 )
1154- t_header = newheader7000, t_header_size = 8 ;
1155- else if (p_version >= kMCStackFileFormatVersion_5_5 )
1156- t_header = newheader5500, t_header_size = 8 ;
1157- else if (p_version >= kMCStackFileFormatVersion_2_7 )
1158- t_header = newheader, t_header_size = 8 ;
1159- else
1160- t_header = header, t_header_size = HEADERSIZE ;
1104+ MCStackFileGetHeaderForVersion (p_version, t_header, t_header_size);
11611105
11621106 if (IO_write (t_header, sizeof (char ), t_header_size, stream) != IO_NORMAL
11631107 || IO_write_uint1 (CHARSET , stream) != IO_NORMAL )
0 commit comments