mirror of
https://git.zap.org.au/git/trader.git
synced 2025-02-02 15:08:13 -05:00
Use separate input and output buffers for scramble() and unscramble()
This commit is contained in:
parent
cec51ded7d
commit
549b2d517d
50
src/fileio.c
50
src/fileio.c
@ -51,12 +51,13 @@ static const unsigned char game_file_crypt_key[] = {
|
||||
|
||||
#define load_game_scanf(_fmt, _var, _cond) \
|
||||
do { \
|
||||
if (fgets(buf, BUFSIZE, file) == NULL) { \
|
||||
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) { \
|
||||
err_exit(_("%s: missing field on line %d"), \
|
||||
filename, lineno); \
|
||||
} \
|
||||
if (sscanf(unscramble(crypt_key, buf, BUFSIZE), _fmt "\n", \
|
||||
&(_var)) != 1) { \
|
||||
if (sscanf(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, \
|
||||
buf, BUFSIZE), _fmt "\n", &(_var)) \
|
||||
!= 1) { \
|
||||
err_exit(_("%s: illegal field on line %d: `%s'"), \
|
||||
filename, lineno, buf); \
|
||||
} \
|
||||
@ -88,11 +89,12 @@ static const unsigned char game_file_crypt_key[] = {
|
||||
char *s; \
|
||||
int len; \
|
||||
\
|
||||
if (fgets(buf, BUFSIZE, file) == NULL) { \
|
||||
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) { \
|
||||
err_exit(_("%s: missing field on line %d"), \
|
||||
filename, lineno); \
|
||||
} \
|
||||
if (strlen(unscramble(crypt_key, buf, BUFSIZE)) == 0) { \
|
||||
if (strlen(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, \
|
||||
buf, BUFSIZE)) == 0) { \
|
||||
err_exit(_("%s: illegal value on line %d"), \
|
||||
filename, lineno); \
|
||||
} \
|
||||
@ -127,11 +129,12 @@ static const unsigned char game_file_crypt_key[] = {
|
||||
char *s; \
|
||||
int len; \
|
||||
\
|
||||
if (fgets(buf, BUFSIZE, file) == NULL) { \
|
||||
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) { \
|
||||
err_exit(_("%s: missing field on line %d"), \
|
||||
filename, lineno); \
|
||||
} \
|
||||
if (strlen(unscramble(crypt_key, buf, BUFSIZE)) == 0) { \
|
||||
if (strlen(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, \
|
||||
buf, BUFSIZE)) == 0) { \
|
||||
err_exit(_("%s: illegal value on line %d"), \
|
||||
filename, lineno); \
|
||||
} \
|
||||
@ -157,8 +160,8 @@ static const unsigned char game_file_crypt_key[] = {
|
||||
#define save_game_printf(_fmt, _var) \
|
||||
do { \
|
||||
snprintf(buf, BUFSIZE, _fmt "\n", _var); \
|
||||
scramble(crypt_key, buf, BUFSIZE); \
|
||||
fprintf(file, "%s", buf); \
|
||||
scramble(&crypt_key, buf, BUFSIZE, bigbuf, BIGBUFSIZE); \
|
||||
fprintf(file, "%s", bigbuf); \
|
||||
} while (0)
|
||||
|
||||
#define save_game_write_int(_var) \
|
||||
@ -224,10 +227,11 @@ bool load_game (int num)
|
||||
int saved_errno, lineno;
|
||||
char *prev_locale;
|
||||
|
||||
char *buf;
|
||||
char *buf, *bigbuf;
|
||||
wchar_t *wcbuf;
|
||||
|
||||
int crypt_key;
|
||||
unsigned char crypt_key;
|
||||
int crypt_key_input;
|
||||
int n, i, j;
|
||||
|
||||
#ifdef USE_UTF8_GAME_FILE
|
||||
@ -239,6 +243,7 @@ bool load_game (int num)
|
||||
assert(num >= 1 && num <= 9);
|
||||
|
||||
buf = xmalloc(BUFSIZE);
|
||||
bigbuf = xmalloc(BIGBUFSIZE);
|
||||
wcbuf = xmalloc(BUFSIZE * sizeof(wchar_t));
|
||||
|
||||
filename = game_filename(num);
|
||||
@ -267,6 +272,7 @@ bool load_game (int num)
|
||||
}
|
||||
|
||||
free(buf);
|
||||
free(bigbuf);
|
||||
free(wcbuf);
|
||||
free(filename);
|
||||
return false;
|
||||
@ -336,9 +342,10 @@ bool load_game (int num)
|
||||
lineno = 4;
|
||||
|
||||
// Read in the game file encryption key
|
||||
if (fscanf(file, "%i\n", &crypt_key) != 1) {
|
||||
if (fscanf(file, "%i\n", &crypt_key_input) != 1) {
|
||||
err_exit(_("%s: illegal or missing field on line %d"), filename, lineno);
|
||||
}
|
||||
crypt_key = (unsigned char) crypt_key_input;
|
||||
lineno++;
|
||||
|
||||
// Read in various game variables
|
||||
@ -377,10 +384,11 @@ bool load_game (int num)
|
||||
|
||||
// Read in galaxy map
|
||||
for (int x = 0; x < MAX_X; x++) {
|
||||
if (fgets(buf, BUFSIZE, file) == NULL) {
|
||||
if (fgets(bigbuf, BIGBUFSIZE, file) == NULL) {
|
||||
err_exit(_("%s: missing field on line %d"), filename, lineno);
|
||||
}
|
||||
if (strlen(unscramble(crypt_key, buf, BUFSIZE)) != MAX_Y + 1) {
|
||||
if (strlen(unscramble(&crypt_key, bigbuf, BIGBUFSIZE, buf, BUFSIZE))
|
||||
!= MAX_Y + 1) {
|
||||
err_exit(_("%s: illegal field on line %d"), filename, lineno);
|
||||
}
|
||||
|
||||
@ -414,6 +422,7 @@ bool load_game (int num)
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
free(bigbuf);
|
||||
free(wcbuf);
|
||||
free(filename);
|
||||
free(prev_locale);
|
||||
@ -428,13 +437,14 @@ bool load_game (int num)
|
||||
bool save_game (int num)
|
||||
{
|
||||
const char *data_dir;
|
||||
char *buf, *filename;
|
||||
char *buf, *bigbuf;
|
||||
char *filename;
|
||||
FILE *file;
|
||||
char *codeset;
|
||||
int saved_errno;
|
||||
char *prev_locale;
|
||||
struct stat statbuf;
|
||||
int crypt_key;
|
||||
unsigned char crypt_key;
|
||||
int i, j, x, y;
|
||||
|
||||
#ifdef USE_UTF8_GAME_FILE
|
||||
@ -446,6 +456,7 @@ bool save_game (int num)
|
||||
assert(num >= 1 && num <= 9);
|
||||
|
||||
buf = xmalloc(BUFSIZE);
|
||||
bigbuf = xmalloc(BIGBUFSIZE);
|
||||
|
||||
crypt_key = option_dont_encrypt ? 0 :
|
||||
game_file_crypt_key[randi(GAME_FILE_CRYPT_KEY_SIZE)];
|
||||
@ -469,6 +480,7 @@ bool save_game (int num)
|
||||
strerror(saved_errno));
|
||||
|
||||
free(buf);
|
||||
free(bigbuf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -489,6 +501,7 @@ bool save_game (int num)
|
||||
"^{File %s: %s^}"), num, filename, strerror(saved_errno));
|
||||
|
||||
free(buf);
|
||||
free(bigbuf);
|
||||
free(filename);
|
||||
return false;
|
||||
}
|
||||
@ -568,8 +581,8 @@ bool save_game (int num)
|
||||
*p++ = '\n';
|
||||
*p = '\0';
|
||||
|
||||
scramble(crypt_key, buf, BUFSIZE);
|
||||
fprintf(file, "%s", buf);
|
||||
scramble(&crypt_key, buf, BUFSIZE, bigbuf, BIGBUFSIZE);
|
||||
fprintf(file, "%s", bigbuf);
|
||||
}
|
||||
|
||||
// Write out a dummy sentinal value
|
||||
@ -589,6 +602,7 @@ bool save_game (int num)
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
free(bigbuf);
|
||||
free(filename);
|
||||
free(prev_locale);
|
||||
return true;
|
||||
|
@ -62,7 +62,7 @@
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 1024 // For various string buffers
|
||||
#define BIGBUFSIZE 2048 // For buffers known to be larger
|
||||
#define BIGBUFSIZE 4096 // For buffers known to be larger
|
||||
|
||||
|
||||
#endif /* included_TRADER_H */
|
||||
|
45
src/utils.c
45
src/utils.c
@ -62,6 +62,27 @@ wchar_t *mon_thousands_sep; // Local monetary thousands separator
|
||||
#define MOD_POSIX_P_CS_PRECEDES 1
|
||||
#define MOD_POSIX_P_SEP_BY_SPACE 0
|
||||
|
||||
// Constants used for scrambling and unscrambling game data
|
||||
#define SCRAMBLE_PAD_CHAR '.'
|
||||
#define UNSCRAMBLE_INVALID (-1)
|
||||
#define UNSCRAMBLE_PAD_CHAR (-2)
|
||||
|
||||
static const char scramble_index[] =
|
||||
"0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-_";
|
||||
|
||||
static const char unscramble_index[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -2, -1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||
-1, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
|
||||
40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, -1, -1, -1, -1, 63,
|
||||
-1, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39,
|
||||
41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
#define UNSCRAMBLE_INDEX_SIZE (sizeof(unscramble_index) / sizeof(unscramble_index[0]))
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Module-specific variables *
|
||||
@ -421,7 +442,9 @@ ssize_t l_strfmon (char *restrict buf, size_t maxsize,
|
||||
/***********************************************************************/
|
||||
// scramble: Scramble (encrypt) the buffer
|
||||
|
||||
char *scramble (int key, char *restrict buf, int bufsize)
|
||||
char *scramble (unsigned char *restrict key,
|
||||
char *restrict inbuf, int inbufsize,
|
||||
char *restrict outbuf, int outbufsize)
|
||||
{
|
||||
/* The algorithm used here is reversable: scramble(scramble(...))
|
||||
will (or, at least, should!) return the same as the original
|
||||
@ -429,11 +452,13 @@ char *scramble (int key, char *restrict buf, int bufsize)
|
||||
function assumes all other characters are permitted in files.
|
||||
This is true on all POSIX systems. */
|
||||
|
||||
if (buf != NULL && key != 0) {
|
||||
char *p = buf;
|
||||
unsigned char k = ~key;
|
||||
assert(outbuf != NULL);
|
||||
|
||||
for (int i = 0; i < bufsize && *p != '\0'; i++, k++, p++) {
|
||||
if (inbuf != NULL && key != NULL && *key != 0) {
|
||||
char *p = inbuf;
|
||||
unsigned char k = ~*key;
|
||||
|
||||
for (int i = 0; i < inbufsize && *p != '\0'; i++, k++, p++) {
|
||||
char c = *p;
|
||||
char r = c ^ k; // Simple encryption: XOR on a moving key
|
||||
|
||||
@ -444,16 +469,20 @@ char *scramble (int key, char *restrict buf, int bufsize)
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
strcpy(outbuf, inbuf);
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
// unscramble: Unscramble (decrypt) the buffer
|
||||
|
||||
char *unscramble (int key, char *restrict buf, int bufsize)
|
||||
char *unscramble (unsigned char *restrict key,
|
||||
char *restrict inbuf, int inbufsize,
|
||||
char *restrict outbuf, int outbufsize)
|
||||
{
|
||||
return scramble(key, buf, bufsize);
|
||||
return scramble(key, inbuf, inbufsize, outbuf, outbufsize);
|
||||
}
|
||||
|
||||
|
||||
|
57
src/utils.h
57
src/utils.h
@ -265,41 +265,54 @@ extern ssize_t l_strfmon (char *restrict buf, size_t maxsize,
|
||||
*/
|
||||
|
||||
/*
|
||||
Function: scramble - Scramble (encrypt) the buffer
|
||||
Parameters: key - Encryption key
|
||||
buf - Pointer to buffer to encrypt
|
||||
bufsize - Size of buffer
|
||||
Returns: char * - Pointer to buffer
|
||||
Function: scramble - Scramble (encrypt) the buffer
|
||||
Parameters: key - Pointer to encryption/decryption key
|
||||
inbuf - Pointer to input buffer to encrypt
|
||||
inbufsize - Size of input buffer
|
||||
outbuf - Pointer to output buffer
|
||||
outbufsize - Size of output buffer
|
||||
Returns: char * - Pointer to output buffer
|
||||
|
||||
This function scrambles (encrypts) the buffer *buf using a trivial
|
||||
in-place encryption algorithm. If key is zero, or buf is NULL or
|
||||
bufsize is less than 1, no encryption takes place.
|
||||
This function scrambles (encrypts) the buffer *inbuf using a trivial
|
||||
encryption algorithm and places the result in *outbuf. If key is NULL
|
||||
or *key is zero, no encryption takes place: the input buffer is copied
|
||||
to the output buffer as-is.
|
||||
|
||||
The buffer should contain a C-style string terminated by '\0'. The
|
||||
characters '\r', '\n' and '\0' are guaranteed to remain the same before
|
||||
and after encryption. At most bufsize bytes are encrypted; buf is
|
||||
returned as the result.
|
||||
The input buffer should contain a C-style string terminated by '\0'.
|
||||
The characters '\r', '\n' and '\0' are guaranteed to remain the same
|
||||
before and after encryption. Note that inbuf and outbuf MUST point to
|
||||
different buffers, and that outbuf typically must be four times larger
|
||||
than inbuf. At most inbufsize bytes are encrypted; outbuf is returned
|
||||
as the result.
|
||||
*/
|
||||
extern char *scramble (int key, char *restrict buf, int bufsize);
|
||||
extern char *scramble (unsigned char *restrict key,
|
||||
char *restrict inbuf, int inbufsize,
|
||||
char *restrict outbuf, int outbufsize);
|
||||
|
||||
|
||||
/*
|
||||
Function: unscramble - Unscramble (decrypt) the buffer
|
||||
Parameters: key - Encryption/decryption key
|
||||
buf - Pointer to buffer to decrypt
|
||||
bufsize - Size of buffer
|
||||
Returns: char * - Pointer to buffer
|
||||
Parameters: key - Pointer to encryption/decryption key
|
||||
inbuf - Pointer to input buffer to decrypt
|
||||
inbufsize - Size of input buffer
|
||||
outbuf - Pointer to output buffer
|
||||
outbufsize - Size of output buffer
|
||||
Returns: char * - Pointer to output buffer
|
||||
|
||||
This function does the reverse of scramble(): it unscrambles (decrypts)
|
||||
the buffer *buf using an in-place algorithm. If key is zero, or buf is
|
||||
NULL or bufsize is less than 1, no decryption takes place.
|
||||
the buffer *inbuf using a trivial algorithm and places the result in
|
||||
*outbuf. If key is NULL or *key is zero, no decryption takes place:
|
||||
the input buffer is copied to the output buffer as-is.
|
||||
|
||||
The buffer should contain a C-style string terminated by '\0'. As for
|
||||
scramble(), the characters '\r', '\n' and '\0' will not be changed (nor
|
||||
will any encrypted character map back to these values). At most
|
||||
bufsize bytes are decrypted; buf is returned as the result.
|
||||
will any encrypted character map back to these values). Note that
|
||||
inbuf and outbuf MUST point to different buffers. At most bufsize
|
||||
bytes are decrypted; outbuf is returned as the result.
|
||||
*/
|
||||
extern char *unscramble (int key, char *restrict buf, int bufsize);
|
||||
extern char *unscramble (unsigned char *restrict key,
|
||||
char *restrict inbuf, int inbufsize,
|
||||
char *restrict outbuf, int outbufsize);
|
||||
|
||||
|
||||
/************************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user