# HG changeset patch # User Gerd Moellmann # Date 953150258 0 # Node ID 2e784b17f85a5d18e46f9f0de96d7a34e5280a06 # Parent f568116325f9bdb4af6e15699a4b54749a768175 (load_dangerous_libraries): New variable. (Vbytecomp_version_regexp): New variable. (safe_to_load_p): New function. (Fload): Handle files not compiled with Emacs specially. (syms_of_lread): New Lisp variable load-dangerous-libraries. diff -r f568116325f9 -r 2e784b17f85a src/lread.c --- a/src/lread.c Wed Mar 15 13:39:19 2000 +0000 +++ b/src/lread.c Wed Mar 15 19:57:38 2000 +0000 @@ -535,6 +535,52 @@ static Lisp_Object load_unwind (); static Lisp_Object load_descriptor_unwind (); +/* Non-zero means load dangerous compiled Lisp files. */ + +int load_dangerous_libraries; + +/* A regular expression used to detect files compiled with Emacs. */ + +static Lisp_Object Vbytecomp_version_regexp; + + +/* Value is non-zero if the file asswociated with file descriptor FD + is a compiled Lisp file that's safe to load. Only files compiled + with Emacs are safe to load. Files compiled with XEmacs can lead + to a crash in Fbyte_code because of an incompatible change in the + byte compiler. */ + +static int +safe_to_load_p (fd) + int fd; +{ + char buf[512]; + int nbytes, i; + int safe_p = 1; + + /* Read the first few bytes from the file, and look for a line + specifying the byte compiler version used. */ + nbytes = emacs_read (fd, buf, sizeof buf - 1); + if (nbytes > 0) + { + buf[nbytes] = '\0'; + + /* Skip to the next newline, skipping over the initial `ELC' + with NUL bytes following it. */ + for (i = 0; i < nbytes && buf[i] != '\n'; ++i) + ; + + if (i < nbytes + && fast_c_string_match_ignore_case (Vbytecomp_version_regexp, + buf + i) < 0) + safe_p = 0; + } + + lseek (fd, 0, SEEK_SET); + return safe_p; +} + + DEFUN ("load", Fload, Sload, 1, 5, 0, "Execute a file of Lisp code named FILE.\n\ First try FILE with `.elc' appended, then try with `.el',\n\ @@ -569,6 +615,7 @@ #ifdef DOS_NT fmode = "rt"; #endif /* DOS_NT */ + int safe_p = 1; CHECK_STRING (file, 0); @@ -649,6 +696,16 @@ struct stat s1, s2; int result; + if (!safe_to_load_p (fd)) + { + safe_p = 0; + if (!load_dangerous_libraries) + error ("File `%s' was not compiled in Emacs", + XSTRING (found)->data); + else if (!NILP (nomessage)) + message_with_string ("File `%s' not compiled in Emacs", found, 1); + } + compiled = 1; #ifdef DOS_NT @@ -671,6 +728,8 @@ } else { + load_source: + /* We are loading a source file (*.el). */ if (!NILP (Vload_source_file_function)) { @@ -699,7 +758,10 @@ if (NILP (nomessage)) { - if (!compiled) + if (!safe_p) + message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...", + file, 1); + else if (!compiled) message_with_string ("Loading %s (source)...", file, 1); else if (newer) message_with_string ("Loading %s (compiled; note, source file is newer)...", @@ -740,7 +802,10 @@ if (!noninteractive && NILP (nomessage)) { - if (!compiled) + if (!safe_p) + message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...done", + file, 1); + else if (!compiled) message_with_string ("Loading %s (source)...done", file, 1); else if (newer) message_with_string ("Loading %s (compiled; note, source file is newer)...done", @@ -3351,6 +3416,16 @@ "List of all DEFVAR_BOOL variables, used by the byte code optimizer."); Vbyte_boolean_vars = Qnil; + DEFVAR_BOOL ("load-dangerous-libraries", &load_dangerous_libraries, + "Non-nil means load dangerous compiled Lisp files.\n\ +Some versions of XEmacs use different byte codes than Emacs. These\n\ +incompatible byte codes can make Emacs crash when it tries to execute\n\ +them."); + load_dangerous_libraries = 0; + + Vbytecomp_version_regexp = build_string ("^;;;.in Emacs version"); + staticpro (&Vbytecomp_version_regexp); + /* Vsource_directory was initialized in init_lread. */ load_descriptor_list = Qnil;