@@ -255,6 +255,7 @@ typedef struct UnpersistInfo {
255255 size_t sizeof_int;
256256 size_t sizeof_size_t ;
257257 size_t vector_components;
258+ uint32_t version;
258259} UnpersistInfo;
259260
260261/* Info shared in persist and unpersist. */
@@ -304,6 +305,11 @@ static char const kHeader[] = { 'A', 'R', 'E', 'S' };
304305/* Floating point number used to check compatibility of loaded data. */
305306static const lua_Number kHeaderNumber = (lua_Number)-1.234567890 ;
306307
308+ /* Version number for the file format. */
309+ static const uint32_t kCurrentVersion = 1 ;
310+ /* Old format magic bytes (0x08, 0x1B, 0xDE, 0x83 in little-endian). */
311+ static const uint32_t kOldMagicBytes = 0x83DE1B08 ;
312+
307313/* Stack indices of some internal values/tables, to avoid magic numbers. */
308314#define PERMIDX 1
309315#define REFTIDX 2
@@ -2812,6 +2818,7 @@ unpersist(Info *info) { /* perms reftbl ... */
28122818static void
28132819p_header (Info *info) {
28142820 WRITE_RAW (kHeader , HEADER_LENGTH);
2821+ WRITE_VALUE (kCurrentVersion , uint32_t );
28152822 WRITE_VALUE (sizeof (lua_Number), uint8_t );
28162823 WRITE_VALUE (kHeaderNumber , lua_Number);
28172824 WRITE_VALUE (sizeof (int ), uint8_t );
@@ -2823,10 +2830,32 @@ static void
28232830u_header (Info *info) {
28242831 char header[HEADER_LENGTH];
28252832 uint8_t number_size;
2833+ uint32_t version_or_magic;
2834+
28262835 READ_RAW (header, HEADER_LENGTH);
28272836 if (strncmp (kHeader , header, HEADER_LENGTH) != 0 ) {
28282837 eris_error (info, " invalid header signature" );
28292838 }
2839+
2840+ /* Read next 4 bytes - could be version (new format) or old magic bytes */
2841+ version_or_magic = READ_VALUE (uint32_t );
2842+
2843+ if (version_or_magic == kOldMagicBytes ) {
2844+ /* Old format detected */
2845+ info->u .upi .version = 0 ;
2846+ /* Seek back 4 bytes so we can re-read the header fields */
2847+ info->u .upi .reader ->seekg (-4 , std::ios_base::cur);
2848+ if (info->u .upi .reader ->fail ()) {
2849+ eris_error (info, ERIS_ERR_READ);
2850+ }
2851+ } else {
2852+ /* New format - interpret as version number */
2853+ info->u .upi .version = version_or_magic;
2854+ if (info->u .upi .version > kCurrentVersion ) {
2855+ eris_error (info, " unsupported file format version (too new)" );
2856+ }
2857+ }
2858+
28302859 number_size = READ_VALUE (uint8_t );
28312860 if (number_size != sizeof (lua_Number)) {
28322861 eris_error (info, " incompatible floating point type" );
0 commit comments