To: vim_dev@googlegroups.com Subject: Patch 7.4.1955 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1955 Problem: Using 32-bit Perl with 64-bit time_t causes memory corruption. (Christian Brabandt) Solution: Use time_T instead of time_t for global variables. (Ken Takata) Files: src/ex_cmds.c, src/globals.h, src/misc2.c, src/proto/ex_cmds.pro, src/proto/misc2.pro, src/structs.h, src/vim.h *** ../vim-7.4.1954/src/ex_cmds.c 2016-06-20 12:50:11.863811251 +0200 --- src/ex_cmds.c 2016-06-26 16:29:19.875494469 +0200 *************** *** 2850,2856 **** * Return the current time in seconds. Calls time(), unless test_settime() * was used. */ ! time_t vim_time(void) { # ifdef FEAT_EVAL --- 2850,2856 ---- * Return the current time in seconds. Calls time(), unless test_settime() * was used. */ ! time_T vim_time(void) { # ifdef FEAT_EVAL *** ../vim-7.4.1954/src/globals.h 2016-06-06 21:07:48.387578685 +0200 --- src/globals.h 2016-06-26 16:29:19.879494399 +0200 *************** *** 1608,1614 **** #endif /* For undo we need to know the lowest time possible. */ ! EXTERN time_t starttime; #ifdef STARTUPTIME EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */ --- 1608,1614 ---- #endif /* For undo we need to know the lowest time possible. */ ! EXTERN time_T starttime; #ifdef STARTUPTIME EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */ *************** *** 1640,1646 **** #endif #ifdef FEAT_EVAL ! EXTERN time_t time_for_testing INIT(= 0); #endif /* --- 1640,1646 ---- #endif #ifdef FEAT_EVAL ! EXTERN time_T time_for_testing INIT(= 0); #endif /* *** ../vim-7.4.1954/src/misc2.c 2016-06-08 21:17:39.053193558 +0200 --- src/misc2.c 2016-06-26 16:29:19.879494399 +0200 *************** *** 6070,6081 **** } /* ! * Read 8 bytes from "fd" and turn them into a time_t, MSB first. */ ! time_t get8ctime(FILE *fd) { ! time_t n = 0; int i; for (i = 0; i < 8; ++i) --- 6070,6081 ---- } /* ! * Read 8 bytes from "fd" and turn them into a time_T, MSB first. */ ! time_T get8ctime(FILE *fd) { ! time_T n = 0; int i; for (i = 0; i < 8; ++i) *************** *** 6137,6147 **** #endif /* ! * Write time_t to file "fd" in 8 bytes. * Returns FAIL when the write failed. */ int ! put_time(FILE *fd, time_t the_time) { char_u buf[8]; --- 6137,6147 ---- #endif /* ! * Write time_T to file "fd" in 8 bytes. * Returns FAIL when the write failed. */ int ! put_time(FILE *fd, time_T the_time) { char_u buf[8]; *************** *** 6150,6175 **** } /* ! * Write time_t to "buf[8]". */ void ! time_to_bytes(time_t the_time, char_u *buf) { int c; int i; int bi = 0; ! time_t wtime = the_time; ! /* time_t can be up to 8 bytes in size, more than long_u, thus we * can't use put_bytes() here. * Another problem is that ">>" may do an arithmetic shift that keeps the * sign. This happens for large values of wtime. A cast to long_u may ! * truncate if time_t is 8 bytes. So only use a cast when it is 4 bytes, * it's safe to assume that long_u is 4 bytes or more and when using 8 * bytes the top bit won't be set. */ for (i = 7; i >= 0; --i) { ! if (i + 1 > (int)sizeof(time_t)) /* ">>" doesn't work well when shifting more bits than avail */ buf[bi++] = 0; else --- 6150,6175 ---- } /* ! * Write time_T to "buf[8]". */ void ! time_to_bytes(time_T the_time, char_u *buf) { int c; int i; int bi = 0; ! time_T wtime = the_time; ! /* time_T can be up to 8 bytes in size, more than long_u, thus we * can't use put_bytes() here. * Another problem is that ">>" may do an arithmetic shift that keeps the * sign. This happens for large values of wtime. A cast to long_u may ! * truncate if time_T is 8 bytes. So only use a cast when it is 4 bytes, * it's safe to assume that long_u is 4 bytes or more and when using 8 * bytes the top bit won't be set. */ for (i = 7; i >= 0; --i) { ! if (i + 1 > (int)sizeof(time_T)) /* ">>" doesn't work well when shifting more bits than avail */ buf[bi++] = 0; else *** ../vim-7.4.1954/src/proto/ex_cmds.pro 2016-06-11 21:04:34.927761279 +0200 --- src/proto/ex_cmds.pro 2016-06-26 16:29:19.879494399 +0200 *************** *** 17,23 **** char_u *viminfo_readstring(vir_T *virp, int off, int convert); void viminfo_writestring(FILE *fd, char_u *p); int barline_writestring(FILE *fd, char_u *s, int remaining_start); ! time_t vim_time(void); void do_fixdel(exarg_T *eap); void print_line_no_prefix(linenr_T lnum, int use_number, int list); void print_line(linenr_T lnum, int use_number, int list); --- 17,23 ---- char_u *viminfo_readstring(vir_T *virp, int off, int convert); void viminfo_writestring(FILE *fd, char_u *p); int barline_writestring(FILE *fd, char_u *s, int remaining_start); ! time_T vim_time(void); void do_fixdel(exarg_T *eap); void print_line_no_prefix(linenr_T lnum, int use_number, int list); void print_line(linenr_T lnum, int use_number, int list); *** ../vim-7.4.1954/src/proto/misc2.pro 2016-01-19 13:21:55.845334290 +0100 --- src/proto/misc2.pro 2016-06-26 16:29:19.879494399 +0200 *************** *** 103,113 **** int get2c(FILE *fd); int get3c(FILE *fd); int get4c(FILE *fd); ! time_t get8ctime(FILE *fd); char_u *read_string(FILE *fd, int cnt); int put_bytes(FILE *fd, long_u nr, int len); ! int put_time(FILE *fd, time_t the_time); ! void time_to_bytes(time_t the_time, char_u *buf); int has_non_ascii(char_u *s); void parse_queued_messages(void); /* vim: set ft=c : */ --- 103,113 ---- int get2c(FILE *fd); int get3c(FILE *fd); int get4c(FILE *fd); ! time_T get8ctime(FILE *fd); char_u *read_string(FILE *fd, int cnt); int put_bytes(FILE *fd, long_u nr, int len); ! int put_time(FILE *fd, time_T the_time); ! void time_to_bytes(time_T the_time, char_u *buf); int has_non_ascii(char_u *s); void parse_queued_messages(void); /* vim: set ft=c : */ *** ../vim-7.4.1954/src/structs.h 2016-06-12 21:20:50.941837428 +0200 --- src/structs.h 2016-06-26 16:29:19.879494399 +0200 *************** *** 113,119 **** fmark_T fmark; char_u *fname; /* file name, used when fnum == 0 */ #ifdef FEAT_VIMINFO ! time_t time_set; #endif } xfmark_T; --- 113,119 ---- fmark_T fmark; char_u *fname; /* file name, used when fnum == 0 */ #ifdef FEAT_VIMINFO ! time_T time_set; #endif } xfmark_T; *************** *** 358,364 **** int uh_flags; /* see below */ pos_T uh_namedm[NMARKS]; /* marks before undo/after redo */ visualinfo_T uh_visual; /* Visual areas before undo/after redo */ ! time_t uh_time; /* timestamp when the change was made */ long uh_save_nr; /* set when the file was saved after the changes in this block */ #ifdef U_DEBUG --- 358,364 ---- int uh_flags; /* see below */ pos_T uh_namedm[NMARKS]; /* marks before undo/after redo */ visualinfo_T uh_visual; /* Visual areas before undo/after redo */ ! time_T uh_time; /* timestamp when the change was made */ long uh_save_nr; /* set when the file was saved after the changes in this block */ #ifdef U_DEBUG *************** *** 1816,1822 **** long b_u_seq_last; /* last used undo sequence number */ long b_u_save_nr_last; /* counter for last file write */ long b_u_seq_cur; /* hu_seq of header below which we are now */ ! time_t b_u_time_cur; /* uh_time of header below which we are now */ long b_u_save_nr_cur; /* file write nr after which we are now */ /* --- 1816,1822 ---- long b_u_seq_last; /* last used undo sequence number */ long b_u_save_nr_last; /* counter for last file write */ long b_u_seq_cur; /* hu_seq of header below which we are now */ ! time_T b_u_time_cur; /* uh_time of header below which we are now */ long b_u_save_nr_cur; /* file write nr after which we are now */ /* *** ../vim-7.4.1954/src/vim.h 2016-06-12 21:20:50.941837428 +0200 --- src/vim.h 2016-06-26 16:31:47.084889008 +0200 *************** *** 1761,1766 **** --- 1761,1777 ---- typedef int proftime_T; /* dummy for function prototypes */ #endif + /* + * When compiling with 32 bit Perl time_t is 32 bits in the Perl code but 64 + * bits elsewhere. That causes memory corruption. Define time_T and use it + * for global variables to avoid that. + */ + #ifdef WIN3264 + typedef __time64_t time_T; + #else + typedef time_t time_T; + #endif + #ifdef _WIN64 typedef __int64 sock_T; #else *** ../vim-7.4.1954/src/version.c 2016-06-26 16:24:01.285129401 +0200 --- src/version.c 2016-06-26 16:30:02.726736152 +0200 *************** *** 755,756 **** --- 755,758 ---- { /* Add new patch number below this line */ + /**/ + 1955, /**/ -- Why is it called "Windows"? "Gates" would be more appropriate... /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///