1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-02 11:21:42 +00:00
emacs/lib-src/update-game-score.c

523 lines
12 KiB
C
Raw Normal View History

2002-03-27 20:57:06 +00:00
/* update-game-score.c --- Update a score file
Copyright (C) 2002-2014 Free Software Foundation, Inc.
Author: Colin Walters <walters@debian.org>
2002-03-27 20:57:06 +00:00
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
2002-03-27 20:57:06 +00:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
2002-03-27 20:57:06 +00:00
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
2002-03-27 20:57:06 +00:00
2009-09-24 01:44:35 +00:00
/* This program allows a game to securely and atomically update a
score file. It should be installed setuid, owned by an appropriate
user like `games'.
Alternatively, it can be compiled without HAVE_SHARED_GAME_DIR
defined, and in that case it will store scores in the user's home
directory (it should NOT be setuid).
2002-03-27 20:57:06 +00:00
Created 2002/03/22.
2002-03-27 20:57:06 +00:00
*/
#include <config.h>
2002-03-27 20:57:06 +00:00
#include <unistd.h>
#include <errno.h>
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
#include <inttypes.h>
#include <limits.h>
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
#include <stdbool.h>
2002-03-27 20:57:06 +00:00
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <pwd.h>
2002-03-27 20:57:06 +00:00
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <getopt.h>
#ifdef WINDOWSNT
#include "ntlib.h"
#endif
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
2002-03-27 20:57:06 +00:00
#define MAX_ATTEMPTS 5
#define MAX_DATA_LEN 1024
static _Noreturn void
usage (int err)
2002-03-27 20:57:06 +00:00
{
fprintf (stdout, "Usage: update-game-score [-m MAX] [-r] [-d DIR] game/scorefile SCORE DATA\n");
2003-02-04 12:00:09 +00:00
fprintf (stdout, " update-game-score -h\n");
fprintf (stdout, " -h\t\tDisplay this help.\n");
fprintf (stdout, " -m MAX\t\tLimit the maximum number of scores to MAX.\n");
fprintf (stdout, " -r\t\tSort the scores in increasing order.\n");
fprintf (stdout, " -d DIR\t\tStore scores in DIR (only if not setuid).\n");
exit (err);
2002-03-27 20:57:06 +00:00
}
static int lock_file (const char *filename, void **state);
static int unlock_file (const char *filename, void *state);
2002-03-27 20:57:06 +00:00
struct score_entry
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
intmax_t score;
char *username;
2002-03-27 20:57:06 +00:00
char *data;
};
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
#define MAX_SCORES min (PTRDIFF_MAX, SIZE_MAX / sizeof (struct score_entry))
static int read_scores (const char *filename, struct score_entry **scores,
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
ptrdiff_t *count, ptrdiff_t *alloc);
static int push_score (struct score_entry **scores, ptrdiff_t *count,
ptrdiff_t *size, struct score_entry const *newscore);
static void sort_scores (struct score_entry *scores, ptrdiff_t count,
bool reverse);
static int write_scores (const char *filename,
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
const struct score_entry *scores, ptrdiff_t count);
static _Noreturn void
lose (const char *msg)
{
2003-02-04 12:00:09 +00:00
fprintf (stderr, "%s\n", msg);
exit (EXIT_FAILURE);
}
2002-03-27 20:57:06 +00:00
static _Noreturn void
lose_syserr (const char *msg)
{
2003-02-04 12:00:09 +00:00
fprintf (stderr, "%s: %s\n", msg, strerror (errno));
exit (EXIT_FAILURE);
}
static char *
get_user_id (void)
{
2003-02-04 12:00:09 +00:00
struct passwd *buf = getpwuid (getuid ());
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (!buf || strchr (buf->pw_name, ' ') || strchr (buf->pw_name, '\n'))
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
intmax_t uid = getuid ();
char *name = malloc (sizeof uid * CHAR_BIT / 3 + 4);
if (name)
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
sprintf (name, "%"PRIdMAX, uid);
return name;
}
return buf->pw_name;
}
static const char *
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
get_prefix (bool running_suid, const char *user_prefix)
{
if (!running_suid && user_prefix == NULL)
2003-02-04 12:00:09 +00:00
lose ("Not using a shared game directory, and no prefix given.");
if (running_suid)
{
#ifdef HAVE_SHARED_GAME_DIR
return HAVE_SHARED_GAME_DIR;
#else
2003-02-04 12:00:09 +00:00
lose ("This program was compiled without HAVE_SHARED_GAME_DIR,\n and should not be suid.");
#endif
}
return user_prefix;
}
2002-03-27 20:57:06 +00:00
int
main (int argc, char **argv)
2002-03-27 20:57:06 +00:00
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
int c;
bool running_suid;
2002-03-27 20:57:06 +00:00
void *lockstate;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
char *scorefile;
char *nl;
Fix warnings produced by compiling with -Wwrite_strings (i.e. use const char *). * b2m.c (concat, fatal): Use const char*. (main): Don't assign labels a string literal. * ebrowse.c (struct member): filename, def_filename is const. (struct sym): filename, sfilename is const. (struct kw): name is const. (add_sym, yyerror, token_string, insert_keyword, main): Use const char*. * emacsclient.c (message, sock_err_message, send_to_emacs) (quote_argument, set_local_socket) (start_daemon_and_retry_set_socket): Use const char*. * etags.c (compressor, language, Ada_suffix, Ada_help, Asm_suffixes) (Asm_help, default_C_suffixes, default_C_help, Cplusplus_suffixes) (Cplusplus_help, Cjava_suffixes, Cobol_suffixes, Cstar_suffixes) (Erlang_suffixes, Erlang_help, Forth_suffixes, Forth_help) (Fortran_suffixes, Fortran_help, HTML_suffixes, HTML_help) (Lisp_suffixes, Lisp_help, Lua_suffixes, Lua_help) (Makefile_filenames, Makefile_help, Objc_suffixes, Objc_help) (Pascal_suffixes, Pascal_help, Perl_suffixes, Perl_interpreters) (Perl_help, PHP_suffixes, PHP_help, plain_C_suffixses, PS_suffixes) (PS_help, Prolog_suffixes, Prolog_help, Python_suffixes, Python_help) (Scheme_suffixes, Scheme_help, TeX_suffixes, TeX_help, Texinfo_suffixes) (Texinfo_help, Yacc_suffixes, Yacc_help, auto_help, none_help) (no_lang_help, print_language_names) (get_language_from_interpreter, get_language_from_filename) (init, make_tag, struct C_stab_entry, write_classname, TEX_defenv) (TEX_decode_env, nocase_tail, savestr, savenstr, fatal, pfatal) (concat): Use const char*. * make-docfile.c (error, fatal, scan_c_file, scan_lisp_file): Use const char *. * movemail.c (fatal, error, concat): Use const char *. * pop.c (pop_multi_first, socket_connection, sendline): Use conat char*. * pop.h (pop_multi_first): Use const char *. (_ARGS): Remove. * sorted-doc.c (error, fatal, states): Use const char *. * update-game-score.c (get_prefix, write_scores, main): Use const char*.
2010-08-11 08:20:34 +00:00
const char *prefix, *user_prefix = NULL;
2002-03-27 20:57:06 +00:00
struct stat buf;
struct score_entry *scores;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
struct score_entry newscore;
bool reverse = false;
ptrdiff_t scorecount, scorealloc;
ptrdiff_t max_scores = MAX_SCORES;
2002-03-27 20:57:06 +00:00
2003-02-04 12:00:09 +00:00
srand (time (0));
2002-03-27 20:57:06 +00:00
2003-02-04 12:00:09 +00:00
while ((c = getopt (argc, argv, "hrm:d:")) != -1)
2002-03-27 20:57:06 +00:00
switch (c)
{
case 'h':
usage (EXIT_SUCCESS);
2002-03-27 20:57:06 +00:00
break;
case 'd':
user_prefix = optarg;
break;
2002-03-27 20:57:06 +00:00
case 'r':
reverse = 1;
break;
case 'm':
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
{
intmax_t m = strtoimax (optarg, 0, 10);
if (m < 0)
usage (EXIT_FAILURE);
max_scores = min (m, MAX_SCORES);
}
2002-03-27 20:57:06 +00:00
break;
default:
usage (EXIT_FAILURE);
2002-03-27 20:57:06 +00:00
}
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (argc - optind != 3)
usage (EXIT_FAILURE);
2003-02-04 12:00:09 +00:00
running_suid = (getuid () != geteuid ());
2003-02-04 12:00:09 +00:00
prefix = get_prefix (running_suid, user_prefix);
2003-02-04 12:00:09 +00:00
scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2);
2002-03-27 20:57:06 +00:00
if (!scorefile)
2003-02-04 12:00:09 +00:00
lose_syserr ("Couldn't allocate score file");
2003-02-04 12:00:09 +00:00
strcpy (scorefile, prefix);
strcat (scorefile, "/");
strcat (scorefile, argv[optind]);
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
newscore.score = strtoimax (argv[optind + 1], 0, 10);
newscore.data = argv[optind + 2];
if (strlen (newscore.data) > MAX_DATA_LEN)
newscore.data[MAX_DATA_LEN] = '\0';
nl = strchr (newscore.data, '\n');
if (nl)
*nl = '\0';
newscore.username = get_user_id ();
if (! newscore.username)
2003-02-04 12:00:09 +00:00
lose_syserr ("Couldn't determine user id");
2003-02-04 14:56:31 +00:00
2003-02-04 12:00:09 +00:00
if (stat (scorefile, &buf) < 0)
lose_syserr ("Failed to access scores file");
2003-02-04 14:56:31 +00:00
2003-02-04 12:00:09 +00:00
if (lock_file (scorefile, &lockstate) < 0)
lose_syserr ("Failed to lock scores file");
2003-02-04 14:56:31 +00:00
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (read_scores (scorefile, &scores, &scorecount, &scorealloc) < 0)
2002-03-27 20:57:06 +00:00
{
2003-02-04 12:00:09 +00:00
unlock_file (scorefile, lockstate);
lose_syserr ("Failed to read scores file");
2002-03-27 20:57:06 +00:00
}
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (push_score (&scores, &scorecount, &scorealloc, &newscore) < 0)
{
unlock_file (scorefile, lockstate);
lose_syserr ("Failed to add score");
}
sort_scores (scores, scorecount, reverse);
/* Limit the number of scores. If we're using reverse sorting, then
also increment the beginning of the array, to skip over the
*smallest* scores. Otherwise, just decrementing the number of
scores suffices, since the smallest is at the end. */
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (scorecount > max_scores)
{
if (reverse)
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
scores += scorecount - max_scores;
scorecount = max_scores;
}
2003-02-04 12:00:09 +00:00
if (write_scores (scorefile, scores, scorecount) < 0)
2002-03-27 20:57:06 +00:00
{
2003-02-04 12:00:09 +00:00
unlock_file (scorefile, lockstate);
lose_syserr ("Failed to write scores file");
2002-03-27 20:57:06 +00:00
}
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (unlock_file (scorefile, lockstate) < 0)
lose_syserr ("Failed to unlock scores file");
exit (EXIT_SUCCESS);
2002-03-27 20:57:06 +00:00
}
static int
read_score (FILE *f, struct score_entry *score)
2002-03-27 20:57:06 +00:00
{
int c;
if ((c = getc (f)) != EOF)
ungetc (c, f);
2003-02-04 12:00:09 +00:00
if (feof (f))
2002-03-27 20:57:06 +00:00
return 1;
for (score->score = 0; (c = getc (f)) != EOF && isdigit (c); )
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (INTMAX_MAX / 10 < score->score)
return -1;
score->score *= 10;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (INTMAX_MAX - (c - '0') < score->score)
return -1;
score->score += c - '0';
}
2003-02-04 12:00:09 +00:00
while ((c = getc (f)) != EOF
&& isspace (c))
;
if (c == EOF)
return -1;
2003-02-04 12:00:09 +00:00
ungetc (c, f);
#ifdef HAVE_GETDELIM
{
size_t count = 0;
score->username = 0;
2003-02-04 12:00:09 +00:00
if (getdelim (&score->username, &count, ' ', f) < 1
|| score->username == NULL)
return -1;
/* Trim the space */
2003-02-04 12:00:09 +00:00
score->username[strlen (score->username)-1] = '\0';
2002-03-27 20:57:06 +00:00
}
#else
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
ptrdiff_t unameread = 0;
ptrdiff_t unamelen = 30;
2003-02-04 12:00:09 +00:00
char *username = malloc (unamelen);
if (!username)
return -1;
2003-02-04 14:56:31 +00:00
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
while ((c = getc (f)) != EOF && c != ' ')
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (unameread >= unamelen - 1)
{
ptrdiff_t unamelen_max = min (PTRDIFF_MAX, SIZE_MAX);
if (unamelen <= unamelen_max / 2)
unamelen *= 2;
else if (unamelen < unamelen_max)
unamelen = unamelen_max;
else
{
errno = ENOMEM;
return -1;
}
username = realloc (username, unamelen);
if (!username)
return -1;
}
username[unameread] = c;
unameread++;
}
2003-02-04 14:56:31 +00:00
if (c == EOF)
return -1;
username[unameread] = '\0';
score->username = username;
}
#endif
2002-03-27 20:57:06 +00:00
#ifdef HAVE_GETLINE
score->data = NULL;
errno = 0;
2002-03-27 20:57:06 +00:00
{
size_t len;
2003-02-04 12:00:09 +00:00
if (getline (&score->data, &len, f) < 0)
2002-03-27 20:57:06 +00:00
return -1;
2003-02-04 12:00:09 +00:00
score->data[strlen (score->data)-1] = '\0';
2002-03-27 20:57:06 +00:00
}
#else
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
ptrdiff_t cur = 0;
ptrdiff_t len = 16;
2003-02-04 12:00:09 +00:00
char *buf = malloc (len);
if (!buf)
return -1;
2003-02-04 12:00:09 +00:00
while ((c = getc (f)) != EOF
&& c != '\n')
{
if (cur >= len-1)
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < len)
{
errno = ENOMEM;
return -1;
}
2003-02-04 12:00:09 +00:00
if (!(buf = realloc (buf, len *= 2)))
return -1;
}
buf[cur] = c;
cur++;
}
score->data = buf;
score->data[cur] = '\0';
}
2002-03-27 20:57:06 +00:00
#endif
return 0;
}
static int
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
read_scores (const char *filename, struct score_entry **scores,
ptrdiff_t *count, ptrdiff_t *alloc)
2002-03-27 20:57:06 +00:00
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
int readval = -1;
ptrdiff_t scorecount = 0;
ptrdiff_t cursize = 0;
struct score_entry *ret = 0;
struct score_entry entry;
2003-02-04 12:00:09 +00:00
FILE *f = fopen (filename, "r");
int retval = -1;
2003-02-04 14:56:31 +00:00
if (!f)
2002-03-27 20:57:06 +00:00
return -1;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
while ((readval = read_score (f, &entry)) == 0)
if (push_score (&ret, &scorecount, &cursize, &entry) < 0)
return -1;
if (readval > 0 && fclose (f) == 0)
{
*count = scorecount;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
*alloc = cursize;
*scores = ret;
retval = 0;
}
return retval;
2002-03-27 20:57:06 +00:00
}
static int
score_compare (const void *a, const void *b)
2002-03-27 20:57:06 +00:00
{
const struct score_entry *sa = (const struct score_entry *) a;
const struct score_entry *sb = (const struct score_entry *) b;
return (sb->score > sa->score) - (sb->score < sa->score);
}
static int
score_compare_reverse (const void *a, const void *b)
2002-03-27 20:57:06 +00:00
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
return score_compare (b, a);
2002-03-27 20:57:06 +00:00
}
int
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
push_score (struct score_entry **scores, ptrdiff_t *count, ptrdiff_t *size,
struct score_entry const *newscore)
2002-03-27 20:57:06 +00:00
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
struct score_entry *newscores = *scores;
if (*count == *size)
{
ptrdiff_t newsize = *size;
if (newsize <= 0)
newsize = 1;
else if (newsize <= MAX_SCORES / 2)
newsize *= 2;
else if (newsize < MAX_SCORES)
newsize = MAX_SCORES;
else
{
errno = ENOMEM;
return -1;
}
newscores = realloc (newscores, sizeof *newscores * newsize);
if (!newscores)
return -1;
*scores = newscores;
*size = newsize;
}
newscores[*count] = *newscore;
2002-03-27 20:57:06 +00:00
(*count) += 1;
return 0;
}
2003-02-04 14:56:31 +00:00
static void
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
sort_scores (struct score_entry *scores, ptrdiff_t count, bool reverse)
2002-03-27 20:57:06 +00:00
{
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
qsort (scores, count, sizeof *scores,
reverse ? score_compare_reverse : score_compare);
2002-03-27 20:57:06 +00:00
}
static int
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
write_scores (const char *filename, const struct score_entry *scores,
ptrdiff_t count)
2002-03-27 20:57:06 +00:00
{
int fd;
2003-02-04 14:56:31 +00:00
FILE *f;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
ptrdiff_t i;
2003-02-04 12:00:09 +00:00
char *tempfile = malloc (strlen (filename) + strlen (".tempXXXXXX") + 1);
2002-03-27 20:57:06 +00:00
if (!tempfile)
return -1;
2003-02-04 12:00:09 +00:00
strcpy (tempfile, filename);
strcat (tempfile, ".tempXXXXXX");
fd = mkostemp (tempfile, 0);
if (fd < 0)
return -1;
Fix the MSDOS build. src/unexcoff.c [MSDOS]: Include libc/atexit.h. (copy_text_and_data): Zero out the atexit chain pointer before dumping Emacs. src/termhooks.h (encode_terminal_code): Update prototype. src/term.c (encode_terminal_code) [DOS_NT]: Make it externally visible for all DOS_NT ports, not just WINDOWSNT. (syms_of_term) [!MSDOS]: Don't define 'tty-menu-*' symbols on MSDOS. src/sysdep.c (emacs_sigaction_init, init_signals): Don't use SIGCHLD unless it is defined. (emacs_pipe) [MSDOS]: Redirect to 'pipe'. src/process.c (close_on_exec, accept4, process_socket): Move into the "ifdef subprocesses" part. (catch_child_signal): Condition by "ifdef subprocesses". (syms_of_process) <Qinternal_default_process_sentinel> <Qinternal_default_process_filter>: Condition by "ifdef subprocesses". src/msdos.h: Add prototypes for new functions. (EINPROGRESS): Define. (O_CLOEXEC): Define to zero. src/msdos.c (check_window_system): Remove unnecessary an incompatible duplicate function. (sys_opendir, readlinkat, faccessat, fstatat, unsetenv): New functions in support of new functionality. src/menu.c (single_menu_item): Add visual indication of submenu also for menus on MSDOS frames. (Fx_popup_menu) [!MSDOS]: Do not call tty_menu_show on MSDOS. src/lisp.h (CHECK_PROCESS) [!subprocesses]: Do not define when async subprocesses aren't supported. src/font.h (FONT_WIDTH) [MSDOS]: MSDOS-specific definition. src/emacs.c (close_output_streams): Zero out errno before calling close_stream. src/dired.c [MSDOS]: Include msdos.h. src/conf_post.h (opendir) [MSDOS]: Redirect to sys_opendir. (DATA_START) [MSDOS]: Define. (SYSTEM_PURESIZE_EXTRA) [MSDOS]: Enlarge by 25K. src/callproc.c (block_child_signal, unblock_child_signal) [MSDOS]: Ifdef away for MSDOS. (record_kill_process) [MSDOS]: Ifdef away the entire body for MSDOS. (call_process_cleanup) [MSDOS]: Ifdef away portions not relevant for MSDOS. (call_process) [MSDOS]: Fix call sequence of dostounix_filename. Use temporary file template that is compatible with mkostemp. Move vfork-related portions under #ifndef MSDOS. (syms_of_callproc): Unify templates of MSDOS and WINDOWSNT. lisp/term/pc-win.el (x-list-fonts, x-get-selection-value): Provide doc strings, as required by snarf-documentation. msdos/sedlisp.inp: msdos/sedlibmk.inp: msdos/sedleim.inp: msdos/sed3v2.inp: msdos/sed2v2.inp: msdos/sed1v2.inp: Update Sed scripts for Emacs 24.4. msdos/inttypes.h: Add PRIdMAX. msdos/INSTALL: Update for Emacs 24.4. msdos/sedadmin.inp: New file.
2014-04-16 13:27:28 +00:00
#ifndef DOS_NT
if (fchmod (fd, 0644) != 0)
return -1;
#endif
f = fdopen (fd, "w");
if (! f)
2002-03-27 20:57:06 +00:00
return -1;
for (i = 0; i < count; i++)
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
if (fprintf (f, "%"PRIdMAX" %s %s\n",
scores[i].score, scores[i].username, scores[i].data)
< 0)
2002-03-27 20:57:06 +00:00
return -1;
if (fclose (f) != 0)
2002-03-27 20:57:06 +00:00
return -1;
if (rename (tempfile, filename) != 0)
2002-03-27 20:57:06 +00:00
return -1;
Fix the MSDOS build. src/unexcoff.c [MSDOS]: Include libc/atexit.h. (copy_text_and_data): Zero out the atexit chain pointer before dumping Emacs. src/termhooks.h (encode_terminal_code): Update prototype. src/term.c (encode_terminal_code) [DOS_NT]: Make it externally visible for all DOS_NT ports, not just WINDOWSNT. (syms_of_term) [!MSDOS]: Don't define 'tty-menu-*' symbols on MSDOS. src/sysdep.c (emacs_sigaction_init, init_signals): Don't use SIGCHLD unless it is defined. (emacs_pipe) [MSDOS]: Redirect to 'pipe'. src/process.c (close_on_exec, accept4, process_socket): Move into the "ifdef subprocesses" part. (catch_child_signal): Condition by "ifdef subprocesses". (syms_of_process) <Qinternal_default_process_sentinel> <Qinternal_default_process_filter>: Condition by "ifdef subprocesses". src/msdos.h: Add prototypes for new functions. (EINPROGRESS): Define. (O_CLOEXEC): Define to zero. src/msdos.c (check_window_system): Remove unnecessary an incompatible duplicate function. (sys_opendir, readlinkat, faccessat, fstatat, unsetenv): New functions in support of new functionality. src/menu.c (single_menu_item): Add visual indication of submenu also for menus on MSDOS frames. (Fx_popup_menu) [!MSDOS]: Do not call tty_menu_show on MSDOS. src/lisp.h (CHECK_PROCESS) [!subprocesses]: Do not define when async subprocesses aren't supported. src/font.h (FONT_WIDTH) [MSDOS]: MSDOS-specific definition. src/emacs.c (close_output_streams): Zero out errno before calling close_stream. src/dired.c [MSDOS]: Include msdos.h. src/conf_post.h (opendir) [MSDOS]: Redirect to sys_opendir. (DATA_START) [MSDOS]: Define. (SYSTEM_PURESIZE_EXTRA) [MSDOS]: Enlarge by 25K. src/callproc.c (block_child_signal, unblock_child_signal) [MSDOS]: Ifdef away for MSDOS. (record_kill_process) [MSDOS]: Ifdef away the entire body for MSDOS. (call_process_cleanup) [MSDOS]: Ifdef away portions not relevant for MSDOS. (call_process) [MSDOS]: Fix call sequence of dostounix_filename. Use temporary file template that is compatible with mkostemp. Move vfork-related portions under #ifndef MSDOS. (syms_of_callproc): Unify templates of MSDOS and WINDOWSNT. lisp/term/pc-win.el (x-list-fonts, x-get-selection-value): Provide doc strings, as required by snarf-documentation. msdos/sedlisp.inp: msdos/sedlibmk.inp: msdos/sedleim.inp: msdos/sed3v2.inp: msdos/sed2v2.inp: msdos/sed1v2.inp: Update Sed scripts for Emacs 24.4. msdos/inttypes.h: Add PRIdMAX. msdos/INSTALL: Update for Emacs 24.4. msdos/sedadmin.inp: New file.
2014-04-16 13:27:28 +00:00
#ifdef DOS_NT
if (chmod (filename, 0644) < 0)
return -1;
#endif
return 0;
2002-03-27 20:57:06 +00:00
}
2003-02-04 14:56:31 +00:00
static int
lock_file (const char *filename, void **state)
2002-03-27 20:57:06 +00:00
{
int fd;
struct stat buf;
2002-03-27 20:57:06 +00:00
int attempts = 0;
Fix warnings produced by compiling with -Wwrite_strings (i.e. use const char *). * b2m.c (concat, fatal): Use const char*. (main): Don't assign labels a string literal. * ebrowse.c (struct member): filename, def_filename is const. (struct sym): filename, sfilename is const. (struct kw): name is const. (add_sym, yyerror, token_string, insert_keyword, main): Use const char*. * emacsclient.c (message, sock_err_message, send_to_emacs) (quote_argument, set_local_socket) (start_daemon_and_retry_set_socket): Use const char*. * etags.c (compressor, language, Ada_suffix, Ada_help, Asm_suffixes) (Asm_help, default_C_suffixes, default_C_help, Cplusplus_suffixes) (Cplusplus_help, Cjava_suffixes, Cobol_suffixes, Cstar_suffixes) (Erlang_suffixes, Erlang_help, Forth_suffixes, Forth_help) (Fortran_suffixes, Fortran_help, HTML_suffixes, HTML_help) (Lisp_suffixes, Lisp_help, Lua_suffixes, Lua_help) (Makefile_filenames, Makefile_help, Objc_suffixes, Objc_help) (Pascal_suffixes, Pascal_help, Perl_suffixes, Perl_interpreters) (Perl_help, PHP_suffixes, PHP_help, plain_C_suffixses, PS_suffixes) (PS_help, Prolog_suffixes, Prolog_help, Python_suffixes, Python_help) (Scheme_suffixes, Scheme_help, TeX_suffixes, TeX_help, Texinfo_suffixes) (Texinfo_help, Yacc_suffixes, Yacc_help, auto_help, none_help) (no_lang_help, print_language_names) (get_language_from_interpreter, get_language_from_filename) (init, make_tag, struct C_stab_entry, write_classname, TEX_defenv) (TEX_decode_env, nocase_tail, savestr, savenstr, fatal, pfatal) (concat): Use const char*. * make-docfile.c (error, fatal, scan_c_file, scan_lisp_file): Use const char *. * movemail.c (fatal, error, concat): Use const char *. * pop.c (pop_multi_first, socket_connection, sendline): Use conat char*. * pop.h (pop_multi_first): Use const char *. (_ARGS): Remove. * sorted-doc.c (error, fatal, states): Use const char *. * update-game-score.c (get_prefix, write_scores, main): Use const char*.
2010-08-11 08:20:34 +00:00
const char *lockext = ".lockfile";
2003-02-04 12:00:09 +00:00
char *lockpath = malloc (strlen (filename) + strlen (lockext) + 60);
2002-03-27 20:57:06 +00:00
if (!lockpath)
return -1;
2003-02-04 12:00:09 +00:00
strcpy (lockpath, filename);
strcat (lockpath, lockext);
2002-03-27 20:57:06 +00:00
*state = lockpath;
trylock:
attempts++;
/* If the lock is over an hour old, delete it. */
2003-02-04 12:00:09 +00:00
if (stat (lockpath, &buf) == 0
&& 60 * 60 < time (0) - buf.st_ctime)
2003-02-04 12:00:09 +00:00
unlink (lockpath);
fd = open (lockpath, O_CREAT | O_EXCL, 0600);
if (fd < 0)
2002-03-27 20:57:06 +00:00
{
if (errno == EEXIST)
{
/* Break the lock; we won't corrupt the file, but we might
lose some scores. */
if (attempts > MAX_ATTEMPTS)
{
2003-02-04 12:00:09 +00:00
unlink (lockpath);
attempts = 0;
}
2003-02-04 12:00:09 +00:00
sleep ((rand () % 2)+1);
2002-03-27 20:57:06 +00:00
goto trylock;
}
else
return -1;
}
2003-02-04 12:00:09 +00:00
close (fd);
2002-03-27 20:57:06 +00:00
return 0;
}
2003-02-04 14:56:31 +00:00
static int
unlock_file (const char *filename, void *state)
2002-03-27 20:57:06 +00:00
{
char *lockpath = (char *) state;
int saved_errno = errno;
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
int ret = unlink (lockpath);
int unlink_errno = errno;
2003-02-04 12:00:09 +00:00
free (lockpath);
update-game-score fixes for -m and integer overflow * update-game-score.c: Include inttypes.h, stdbool.h. (min): New macro, if not already defined. (MAX_SCORES, main): Limit the maximum number of scores only from limits imposed by the underyling platform, instead of the arbitrary value 200. (struct score_entry, main, read_score, write_score): Scores are now intmax_t, not long. (get_user_id): Reject user names containing spaces or newlines, as they would mess up the score file. Allow uids that don't fit in 'long'. Increase the size of the buffer, to avoid overrun in weird cases. (get_prefix, main): Use bool for boolean. (main): Rewrite expr to avoid possibility of signed integer overflow. Don't allow newlines in data, as this would mess up the score file. Check for memory allocation failure when adding the new score, or when unlockint the file. Implement -m. (read_score): Check for integer overflow when reading a score. (read_score) [!HAVE_GETDELIM]: Check for integer overflow when data gets very long. Check only for space to delimit names, since that's what's done in the HAVE_GETDELIM case. (read_scores): New parameter ALLOC. Change counts to ptrdiff_t. All uses changed. Use push_score to add individual scores; that's simpler than repeating its contents. (score_compare_reverse): Simplify. (push_score): New parameter SIZE. Change counts to ptrdiff_t. All uses changed. Check for integer overflow of size calculation. (sort_scores, write_scores): Change counts to ptrdiff_t. (unlock_file): Preserve errno on success, so that storage exhaustion is diagnosed correctly. Fixes: debbugs:16428
2014-01-19 08:50:53 +00:00
errno = ret < 0 ? unlink_errno : saved_errno;
2002-03-27 20:57:06 +00:00
return ret;
}
2003-09-01 15:45:59 +00:00
/* update-game-score.c ends here */