Skip to content

Commit fc17853

Browse files
committed
Add a version field to Ares
1 parent c46aacf commit fc17853

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

ARES.bt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ local uint64 refPositions[0xFFFF] = {0};
526526
typedef struct {
527527
char sig[4] <bgcolor=0x33aaff>; /* Header signature for rudimentary validation */
528528
Assert(sig == "ARES");
529+
uint32_t version;
529530
uint8_t sizeof_number; /* sizeof(lua_Number) to check type compatibility */
530531
lua_Number test; /* -1.234567890 to check representation compatibility */
531532
uint8_t sizeof_int; /* sizeof(int) in persisted data */
@@ -536,6 +537,9 @@ typedef struct {
536537
* "size" and check for truncation when reading, if necessary. */
537538
} Header <bgcolor=cLtRed>;
538539

540+
// Define this up here so structs can reference the version
541+
Header header; /* The header used for basic validation. */
542+
539543
string ReadObject(Object &o) {
540544
// ref should be non-zero if present
541545
if (o.ourRef) {
@@ -827,5 +831,4 @@ struct PermKey {
827831
* value in the permanents table when unpersisting has the correct type. */
828832
};
829833

830-
Header header; /* The header used for basic validation. */
831834
Object rootobj; /* The root object that was persisted. */

VM/src/ares.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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. */
305306
static 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 ... */
28122818
static void
28132819
p_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
28232830
u_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

Comments
 (0)