Oops, I forgot to actually implement the checksumming code for the new

savefile format, so any savefiles generated yesterday can be tampered
with. Oh well. While here, tidy up the crc code.
This commit is contained in:
dholland 2012-01-08 18:16:00 +00:00
parent cdbdbc76a5
commit 158b740733
3 changed files with 65 additions and 38 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: crc.c,v 1.12 2012/01/07 18:08:35 dholland Exp $ */
/* $NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $ */
/*-
* Copyright (c) 1993
@ -38,13 +38,13 @@
static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 5/31/93";
static char ORIGINAL_sccsid[] = "@(#)crc.c 5.2 (Berkeley) 4/4/91";
#else
__RCSID("$NetBSD: crc.c,v 1.12 2012/01/07 18:08:35 dholland Exp $");
__RCSID("$NetBSD: crc.c,v 1.13 2012/01/08 18:16:00 dholland Exp $");
#endif
#endif /* not lint */
#include "extern.h"
static const unsigned long crctab[] = {
static const uint32_t crctab[256] = {
0x7fffffff,
0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e,
@ -98,6 +98,7 @@ static const unsigned long crctab[] = {
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02,
0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*
* crc --
* Compute a POSIX.2 checksum. This routine modified by Jim Gillogly
@ -106,31 +107,39 @@ static const unsigned long crctab[] = {
* it.
*/
static unsigned long crcval;
static unsigned int step;
void
crc_start(void)
crc_start(struct crcstate *c)
{
crcval = step = 0;
c->crcval = 0;
c->step = 0;
}
/* Process nr bytes at a time; ptr points to them */
unsigned long
crc(const char *ptr, int nr)
/*
* Process NUM bytes pointed to by DATA
*/
void
crc_add(struct crcstate *c, const void *data, size_t num)
{
int i;
const char *p;
const unsigned char *udata;
size_t pos;
unsigned x;
while (nr > 0)
for (p = ptr; nr--; ++p) {
i = (crcval >> 24 ^ (unsigned char)*p) & 0xff;
if (i == 0) {
i = step++;
if (step >= sizeof(crctab) / sizeof(crctab[0]))
step = 0;
udata = data;
pos = 0;
while (pos < num) {
x = (c->crcval >> 24 ^ udata[pos++]) & 0xff;
if (x == 0) {
x = c->step++;
if (c->step >= __arraycount(crctab)) {
c->step = 0;
}
crcval = (crcval << 8) ^ crctab[i];
}
return crcval & 0xffffffff; /* Mask to 32 bits. */
c->crcval = (c->crcval << 8) ^ crctab[x];
}
}
uint32_t
crc_get(struct crcstate *c)
{
return c->crcval;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.14 2009/10/21 01:07:44 snj Exp $ */
/* $NetBSD: extern.h,v 1.15 2012/01/08 18:16:00 dholland Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
@ -27,8 +27,14 @@
#include <string.h>
/* crc.c */
void crc_start(void);
unsigned long crc(const char *, int);
struct crcstate {
uint32_t crcval;
unsigned step;
};
void crc_start(struct crcstate *);
void crc_add(struct crcstate *, const void *, size_t);
uint32_t crc_get(struct crcstate *);
/* done.c */
int score(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: save.c,v 1.12 2012/01/07 22:23:16 dholland Exp $ */
/* $NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: save.c,v 1.12 2012/01/07 22:23:16 dholland Exp $");
__RCSID("$NetBSD: save.c,v 1.13 2012/01/08 18:16:00 dholland Exp $");
#endif
#endif /* not lint */
@ -60,13 +60,14 @@ struct savefile {
bool warned;
unsigned bintextpos;
uint32_t key;
uint32_t sum;
struct crcstate crc;
unsigned char pad[8];
unsigned padpos;
};
#define BINTEXT_WIDTH 60
#define FORMAT_VERSION 1
#define FORMAT_VERSION 2
#define FORMAT_VERSION_NOSUM 1
static const char header[] = "Adventure save file\n";
////////////////////////////////////////////////////////////
@ -133,7 +134,7 @@ savefile_open(const char *name, bool forwrite)
sf->warned = false;
sf->bintextpos = 0;
sf->key = 0;
sf->sum = 0;
crc_start(&sf->crc);
memset(sf->pad, 0, sizeof(sf->pad));
sf->padpos = 0;
return sf;
@ -362,7 +363,7 @@ static void
savefile_key(struct savefile *sf, uint32_t key)
{
sf->key = 0;
sf->sum = 0;
crc_start(&sf->crc);
hash(&sf->key, sizeof(sf->key), sf->pad, sizeof(sf->pad));
sf->padpos = 0;
}
@ -412,6 +413,7 @@ savefile_cread(struct savefile *sf, void *data, size_t len)
}
pos += amt;
}
crc_add(&sf->crc, data, len);
return 0;
}
@ -443,6 +445,7 @@ savefile_cwrite(struct savefile *sf, const void *data, size_t len)
}
pos += amt;
}
crc_add(&sf->crc, data, len);
return 0;
}
@ -528,6 +531,7 @@ compat_restore(const char *infile)
char *s;
long sum, cksum = 0;
int i;
struct crcstate crc;
if ((in = fopen(infile, "rb")) == NULL) {
fprintf(stderr,
@ -544,9 +548,10 @@ compat_restore(const char *infile)
}
fclose(in);
crc_start(); /* See if she cheated */
crc_start(&crc); /* See if she cheated */
for (p = compat_savearray; p->address != NULL; p++)
cksum = crc(p->address, p->width);
crc_add(&crc, p->address, p->width);
cksum = crc_get(&crc);
if (sum != cksum) /* Tsk tsk */
return 2; /* Altered the file */
/* We successfully restored, so this really was a save file */
@ -661,7 +666,7 @@ save(const char *outfile)
uint32_t key, writeable_key;
uint32_t version;
unsigned i, j, n;
uint32_t val;
uint32_t val, sum;
sf = savefile_open(outfile, true);
if (sf == NULL) {
@ -732,8 +737,8 @@ save(const char *outfile)
}
#endif
sf->sum = htonl(sf->sum);
if (savefile_binwrite(sf, &sf->sum, sizeof(&sf->sum))) {
sum = htonl(crc_get(&sf->crc));
if (savefile_binwrite(sf, &sum, sizeof(&sum))) {
savefile_close(sf);
return 1;
}
@ -753,6 +758,7 @@ restore(const char *infile)
uint32_t version, key, sum;
unsigned i, j, n;
uint32_t val;
bool skipsum = false;
sf = savefile_open(infile, false);
if (sf == NULL) {
@ -777,7 +783,13 @@ restore(const char *infile)
return 1;
}
version = ntohl(version);
if (version != FORMAT_VERSION) {
switch (version) {
case FORMAT_VERSION:
break;
case FORMAT_VERSION_NOSUM:
skipsum = true;
break;
default:
savefile_close(sf);
fprintf(stderr,
"Oh dear, that file must be from the future. I don't know"
@ -840,7 +852,7 @@ restore(const char *infile)
}
sum = ntohl(sum);
/* See if she cheated */
if (sum != sf->sum) {
if (!skipsum && sum != crc_get(&sf->crc)) {
/* Tsk tsk, altered the file */
savefile_close(sf);
return 2;