diff options
| author | Eric M. Ludlam | 2012-01-09 14:12:11 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-01-09 14:12:11 +0800 |
| commit | a62d5ee188dcb532088a15b0a2f066d3305b2eda (patch) | |
| tree | 574682d524389c5b21730c379edf818f852d69e2 | |
| parent | 866b58d61afd2eccfed53d1707bea233bde3c030 (diff) | |
| download | emacs-a62d5ee188dcb532088a15b0a2f066d3305b2eda.tar.gz emacs-a62d5ee188dcb532088a15b0a2f066d3305b2eda.zip | |
Fix EDE security flaw involving loading arbitrary Lisp from Project.ede.
* lisp/ede.el (ede-project-directories): New option.
(ede-directory-safe-p): Check it.
(ede-initialize-state-current-buffer, ede, ede-new)
(ede-check-project-directory, ede-rescan-toplevel)
(ede-load-project-file, ede-parent-project, ede-current-project):
(ede-target-parent): Avoid loading in a project unless it is safe,
since it may involve malicious code. This security flaw was
pointed out by Hiroshi Oota.
* lisp/ede/auto.el (ede-project-autoload): Add safe-p slot.
(ede-project-class-files): Projects using Project.ede are unsafe.
(ede-auto-load-project): New method.
* lisp/ede/simple.el (ede-project-class-files): Mark as unsafe.
| -rw-r--r-- | lisp/cedet/ChangeLog | 17 | ||||
| -rw-r--r-- | lisp/cedet/ede.el | 215 | ||||
| -rw-r--r-- | lisp/cedet/ede/auto.el | 28 | ||||
| -rw-r--r-- | lisp/cedet/ede/simple.el | 3 |
4 files changed, 211 insertions, 52 deletions
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog index d8a4209cc98..dc43253fcd7 100644 --- a/lisp/cedet/ChangeLog +++ b/lisp/cedet/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2012-01-09 Eric Ludlam <zappo@gnu.org> | ||
| 2 | |||
| 3 | * ede.el (ede-project-directories): New option. | ||
| 4 | (ede-directory-safe-p): Check it. | ||
| 5 | (ede-initialize-state-current-buffer, ede, ede-new) | ||
| 6 | (ede-check-project-directory, ede-rescan-toplevel) | ||
| 7 | (ede-load-project-file, ede-parent-project, ede-current-project): | ||
| 8 | (ede-target-parent): Avoid loading in a project unless it is safe, | ||
| 9 | since it may involve malicious code. This security flaw was | ||
| 10 | pointed out by Hiroshi Oota. | ||
| 11 | |||
| 12 | * ede/auto.el (ede-project-autoload): Add safe-p slot. | ||
| 13 | (ede-project-class-files): Projects using Project.ede are unsafe. | ||
| 14 | (ede-auto-load-project): New method. | ||
| 15 | |||
| 16 | * ede/simple.el (ede-project-class-files): Mark as unsafe. | ||
| 17 | |||
| 1 | 2011-04-13 Juanma Barranquero <lekktu@gmail.com> | 18 | 2011-04-13 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 19 | ||
| 3 | * ede/pconf.el (ede-proj-tweak-autoconf, ede-proj-flush-autoconf): | 20 | * ede/pconf.el (ede-proj-tweak-autoconf, ede-proj-flush-autoconf): |
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index f0450d539a3..c3a223fad80 100644 --- a/lisp/cedet/ede.el +++ b/lisp/cedet/ede.el | |||
| @@ -94,6 +94,42 @@ target willing to take the file. 'never means never perform the check." | |||
| 94 | :group 'ede | 94 | :group 'ede |
| 95 | :type 'sexp) ; make this be a list of options some day | 95 | :type 'sexp) ; make this be a list of options some day |
| 96 | 96 | ||
| 97 | (defcustom ede-project-directories nil | ||
| 98 | "Directories in which EDE may search for project files. | ||
| 99 | If the value is t, EDE may search in any directory. | ||
| 100 | |||
| 101 | If the value is a function, EDE calls that function with one | ||
| 102 | argument, the directory name; the function should return t iff | ||
| 103 | EDE should look for project files in the directory. | ||
| 104 | |||
| 105 | Otherwise, the value should be a list of fully-expanded directory | ||
| 106 | names. EDE searches for project files only in those directories. | ||
| 107 | If you invoke the commands \\[ede] or \\[ede-new] on a directory | ||
| 108 | that is not listed, Emacs will offer to add it to the list. | ||
| 109 | |||
| 110 | Any other value disables searching for EDE project files." | ||
| 111 | :group 'ede | ||
| 112 | :type '(choice (const :tag "Any directory" t) | ||
| 113 | (repeat :tag "List of directories" | ||
| 114 | (directory)) | ||
| 115 | (function :tag "Predicate")) | ||
| 116 | :version "23.4" | ||
| 117 | :risky t) | ||
| 118 | |||
| 119 | (defun ede-directory-safe-p (dir) | ||
| 120 | "Return non-nil if DIR is a safe directory to load projects from. | ||
| 121 | Projects that do not load a project definition as Emacs Lisp code | ||
| 122 | are safe, and can be loaded automatically. Other project types, | ||
| 123 | such as those created with Project.ede files, are safe only if | ||
| 124 | specified by `ede-project-directories'." | ||
| 125 | (setq dir (directory-file-name (expand-file-name dir))) | ||
| 126 | ;; Load only if allowed by `ede-project-directories'. | ||
| 127 | (or (eq ede-project-directories t) | ||
| 128 | (and (functionp ede-project-directories) | ||
| 129 | (funcall ede-project-directories dir)) | ||
| 130 | (and (listp ede-project-directories) | ||
| 131 | (member dir ede-project-directories)))) | ||
| 132 | |||
| 97 | 133 | ||
| 98 | ;;; Management variables | 134 | ;;; Management variables |
| 99 | 135 | ||
| @@ -419,24 +455,42 @@ provided `global-ede-mode' is enabled." | |||
| 419 | Sets buffer local variables for EDE." | 455 | Sets buffer local variables for EDE." |
| 420 | (let* ((ROOT nil) | 456 | (let* ((ROOT nil) |
| 421 | (proj (ede-directory-get-open-project default-directory | 457 | (proj (ede-directory-get-open-project default-directory |
| 422 | 'ROOT))) | 458 | 'ROOT)) |
| 459 | (projauto nil)) | ||
| 460 | |||
| 423 | (when (or proj ROOT | 461 | (when (or proj ROOT |
| 424 | (ede-directory-project-p default-directory t)) | 462 | ;; If there is no open project, look up the project |
| 463 | ;; autoloader to see if we should initialize. | ||
| 464 | (setq projauto (ede-directory-project-p default-directory t))) | ||
| 465 | |||
| 466 | (when (and (not proj) projauto) | ||
| 467 | |||
| 468 | ;; No project was loaded, but we have a project description | ||
| 469 | ;; object. This means that we can check if it is a safe | ||
| 470 | ;; project to load before requesting it to be loaded. | ||
| 425 | 471 | ||
| 426 | (when (not proj) | 472 | (when (or (oref projauto safe-p) |
| 427 | ;; @todo - this could be wasteful. | 473 | ;; The project style is not safe, so check if it is |
| 428 | (setq proj (ede-load-project-file default-directory 'ROOT))) | 474 | ;; in `ede-project-directories'. |
| 475 | (let ((top (ede-toplevel-project default-directory))) | ||
| 476 | (ede-directory-safe-p top))) | ||
| 429 | 477 | ||
| 430 | (setq ede-object (ede-buffer-object (current-buffer) | 478 | ;; The project is safe, so load it in. |
| 479 | (setq proj (ede-load-project-file default-directory 'ROOT)))) | ||
| 480 | |||
| 481 | ;; Only initialize EDE state in this buffer if we found a project. | ||
| 482 | (when proj | ||
| 483 | |||
| 484 | (setq ede-object (ede-buffer-object (current-buffer) | ||
| 431 | 'ede-object-project)) | 485 | 'ede-object-project)) |
| 432 | 486 | ||
| 433 | (setq ede-object-root-project | 487 | (setq ede-object-root-project |
| 434 | (or ROOT (ede-project-root ede-object-project))) | 488 | (or ROOT (ede-project-root ede-object-project))) |
| 435 | 489 | ||
| 436 | (if (and (not ede-object) ede-object-project) | 490 | (if (and (not ede-object) ede-object-project) |
| 437 | (ede-auto-add-to-target)) | 491 | (ede-auto-add-to-target)) |
| 438 | 492 | ||
| 439 | (ede-apply-target-options)))) | 493 | (ede-apply-target-options))))) |
| 440 | 494 | ||
| 441 | (defun ede-reset-all-buffers (onoff) | 495 | (defun ede-reset-all-buffers (onoff) |
| 442 | "Reset all the buffers due to change in EDE. | 496 | "Reset all the buffers due to change in EDE. |
| @@ -555,13 +609,73 @@ of objects with the `ede-want-file-p' method." | |||
| 555 | 609 | ||
| 556 | ;;; Interactive method invocations | 610 | ;;; Interactive method invocations |
| 557 | ;; | 611 | ;; |
| 558 | (defun ede (file) | 612 | (defun ede (dir) |
| 559 | "Start up EDE on something. | 613 | "Start up EDE for directory DIR. |
| 560 | Argument FILE is the file or directory to load a project from." | 614 | If DIR has an existing project file, load it. |
| 561 | (interactive "fProject File: ") | 615 | Otherwise, create a new project for DIR." |
| 562 | (if (not (file-exists-p file)) | 616 | (interactive |
| 563 | (ede-new file) | 617 | ;; When choosing a directory to turn on, and we see some directory here, |
| 564 | (ede-load-project-file (file-name-directory file)))) | 618 | ;; provide that as the default. |
| 619 | (let* ((top (ede-toplevel-project default-directory)) | ||
| 620 | (promptdflt (or top default-directory))) | ||
| 621 | (list (read-directory-name "Project directory: " | ||
| 622 | promptdflt promptdflt t)))) | ||
| 623 | (unless (file-directory-p dir) | ||
| 624 | (error "%s is not a directory" dir)) | ||
| 625 | (when (ede-directory-get-open-project dir) | ||
| 626 | (error "%s already has an open project associated with it" dir)) | ||
| 627 | |||
| 628 | ;; Check if the directory has been added to the list of safe | ||
| 629 | ;; directories. It can also add the directory to the safe list if | ||
| 630 | ;; the user chooses. | ||
| 631 | (if (ede-check-project-directory dir) | ||
| 632 | (progn | ||
| 633 | ;; If there is a project in DIR, load it, otherwise do | ||
| 634 | ;; nothing. | ||
| 635 | (ede-load-project-file dir) | ||
| 636 | |||
| 637 | ;; Check if we loaded anything on the previous line. | ||
| 638 | (if (ede-current-project dir) | ||
| 639 | |||
| 640 | ;; We successfully opened an existing project. Some open | ||
| 641 | ;; buffers may also be referring to this project. | ||
| 642 | ;; Resetting all the buffers will get them to also point | ||
| 643 | ;; at this new open project. | ||
| 644 | (ede-reset-all-buffers 1) | ||
| 645 | |||
| 646 | ;; ELSE | ||
| 647 | ;; There was no project, so switch to `ede-new' which is how | ||
| 648 | ;; a user can select a new kind of project to create. | ||
| 649 | (let ((default-directory (expand-file-name dir))) | ||
| 650 | (call-interactively 'ede-new)))) | ||
| 651 | |||
| 652 | ;; If the proposed directory isn't safe, then say so. | ||
| 653 | (error "%s is not an allowed project directory in `ede-project-directories'" | ||
| 654 | dir))) | ||
| 655 | |||
| 656 | (defun ede-check-project-directory (dir) | ||
| 657 | "Check if DIR should be in `ede-project-directories'. | ||
| 658 | If it is not, try asking the user if it should be added; if so, | ||
| 659 | add it and save `ede-project-directories' via Customize. | ||
| 660 | Return nil iff DIR should not be in `ede-project-directories'." | ||
| 661 | (setq dir (directory-file-name (expand-file-name dir))) ; strip trailing / | ||
| 662 | (or (eq ede-project-directories t) | ||
| 663 | (and (functionp ede-project-directories) | ||
| 664 | (funcall ede-project-directories dir)) | ||
| 665 | ;; If `ede-project-directories' is a list, maybe add it. | ||
| 666 | (when (listp ede-project-directories) | ||
| 667 | (or (member dir ede-project-directories) | ||
| 668 | (when (y-or-n-p (format "`%s' is not listed in `ede-project-directories'. | ||
| 669 | Add it to the list of allowed project directories? " | ||
| 670 | dir)) | ||
| 671 | (push dir ede-project-directories) | ||
| 672 | ;; If possible, save `ede-project-directories'. | ||
| 673 | (if (or custom-file user-init-file) | ||
| 674 | (let ((coding-system-for-read nil)) | ||
| 675 | (customize-save-variable | ||
| 676 | 'ede-project-directories | ||
| 677 | ede-project-directories))) | ||
| 678 | t))))) | ||
| 565 | 679 | ||
| 566 | (defun ede-new (type &optional name) | 680 | (defun ede-new (type &optional name) |
| 567 | "Create a new project starting of project type TYPE. | 681 | "Create a new project starting of project type TYPE. |
| @@ -596,6 +710,11 @@ Optional argument NAME is the name to give this project." | |||
| 596 | (error "Cannot create project in non-existent directory %s" default-directory)) | 710 | (error "Cannot create project in non-existent directory %s" default-directory)) |
| 597 | (when (not (file-writable-p default-directory)) | 711 | (when (not (file-writable-p default-directory)) |
| 598 | (error "No write permissions for %s" default-directory)) | 712 | (error "No write permissions for %s" default-directory)) |
| 713 | (unless (ede-check-project-directory default-directory) | ||
| 714 | (error "%s is not an allowed project directory in `ede-project-directories'" | ||
| 715 | default-directory)) | ||
| 716 | ;; Make sure the project directory is loadable in the future. | ||
| 717 | (ede-check-project-directory default-directory) | ||
| 599 | ;; Create the project | 718 | ;; Create the project |
| 600 | (let* ((obj (object-assoc type 'name ede-project-class-files)) | 719 | (let* ((obj (object-assoc type 'name ede-project-class-files)) |
| 601 | (nobj (let ((f (oref obj file)) | 720 | (nobj (let ((f (oref obj file)) |
| @@ -629,6 +748,10 @@ Optional argument NAME is the name to give this project." | |||
| 629 | (ede-add-subproject pp nobj) | 748 | (ede-add-subproject pp nobj) |
| 630 | (ede-commit-project pp))) | 749 | (ede-commit-project pp))) |
| 631 | (ede-commit-project nobj)) | 750 | (ede-commit-project nobj)) |
| 751 | ;; Once the project is created, load it again. This used to happen | ||
| 752 | ;; lazily, but with project loading occurring less often and with | ||
| 753 | ;; security in mind, this is now the safe time to reload. | ||
| 754 | (ede-load-project-file default-directory) | ||
| 632 | ;; Have the menu appear | 755 | ;; Have the menu appear |
| 633 | (setq ede-minor-mode t) | 756 | (setq ede-minor-mode t) |
| 634 | ;; Allert the user | 757 | ;; Allert the user |
| @@ -651,11 +774,16 @@ ARGS are additional arguments to pass to method sym." | |||
| 651 | (defun ede-rescan-toplevel () | 774 | (defun ede-rescan-toplevel () |
| 652 | "Rescan all project files." | 775 | "Rescan all project files." |
| 653 | (interactive) | 776 | (interactive) |
| 654 | (let ((toppath (ede-toplevel-project default-directory)) | 777 | (if (not (ede-directory-get-open-project default-directory)) |
| 655 | (ede-deep-rescan t)) | 778 | ;; This directory isn't open. Can't rescan. |
| 656 | (project-rescan (ede-load-project-file toppath)) | 779 | (error "Attempt to rescan a project that isn't open") |
| 657 | (ede-reset-all-buffers 1) | 780 | |
| 658 | )) | 781 | ;; Continue |
| 782 | (let ((toppath (ede-toplevel-project default-directory)) | ||
| 783 | (ede-deep-rescan t)) | ||
| 784 | |||
| 785 | (project-rescan (ede-load-project-file toppath)) | ||
| 786 | (ede-reset-all-buffers 1)))) | ||
| 659 | 787 | ||
| 660 | (defun ede-new-target (&rest args) | 788 | (defun ede-new-target (&rest args) |
| 661 | "Create a new target specific to this type of project file. | 789 | "Create a new target specific to this type of project file. |
| @@ -891,7 +1019,7 @@ Optional ROOTRETURN will return the root project for DIR." | |||
| 891 | ;; Do the load | 1019 | ;; Do the load |
| 892 | ;;(message "EDE LOAD : %S" file) | 1020 | ;;(message "EDE LOAD : %S" file) |
| 893 | (let* ((file dir) | 1021 | (let* ((file dir) |
| 894 | (path (expand-file-name (file-name-directory file))) | 1022 | (path (file-name-as-directory (expand-file-name dir))) |
| 895 | (pfc (ede-directory-project-p path)) | 1023 | (pfc (ede-directory-project-p path)) |
| 896 | (toppath nil) | 1024 | (toppath nil) |
| 897 | (o nil)) | 1025 | (o nil)) |
| @@ -920,13 +1048,11 @@ Optional ROOTRETURN will return the root project for DIR." | |||
| 920 | ;; See if it's been loaded before | 1048 | ;; See if it's been loaded before |
| 921 | (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file | 1049 | (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file |
| 922 | ede-projects)) | 1050 | ede-projects)) |
| 923 | (if (not o) | 1051 | |
| 924 | ;; If not, get it now. | 1052 | ;; If not open yet, load it. |
| 925 | (let ((ede-constructing pfc)) | 1053 | (unless o |
| 926 | (setq o (funcall (oref pfc load-type) toppath)) | 1054 | (let ((ede-constructing pfc)) |
| 927 | (when (not o) | 1055 | (setq o (ede-auto-load-project pfc toppath)))) |
| 928 | (error "Project type error: :load-type failed to create a project")) | ||
| 929 | (ede-add-project-to-global-list o))) | ||
| 930 | 1056 | ||
| 931 | ;; Return the found root project. | 1057 | ;; Return the found root project. |
| 932 | (when rootreturn (set rootreturn o)) | 1058 | (when rootreturn (set rootreturn o)) |
| @@ -980,13 +1106,7 @@ Optional argument OBJ is an object to find the parent of." | |||
| 980 | (and root | 1106 | (and root |
| 981 | (ede-find-subproject-for-directory root updir)) | 1107 | (ede-find-subproject-for-directory root updir)) |
| 982 | ;; Try the all structure based search. | 1108 | ;; Try the all structure based search. |
| 983 | (ede-directory-get-open-project updir) | 1109 | (ede-directory-get-open-project updir)))))))) |
| 984 | ;; Load up the project file as a last resort. | ||
| 985 | ;; Last resort since it uses file-truename, and other | ||
| 986 | ;; slow features. | ||
| 987 | (and (ede-directory-project-p updir) | ||
| 988 | (ede-load-project-file | ||
| 989 | (file-name-as-directory updir)))))))))) | ||
| 990 | 1110 | ||
| 991 | (defun ede-current-project (&optional dir) | 1111 | (defun ede-current-project (&optional dir) |
| 992 | "Return the current project file. | 1112 | "Return the current project file. |
| @@ -1000,11 +1120,7 @@ If optional DIR is provided, get the project for DIR instead." | |||
| 1000 | ;; No current project. | 1120 | ;; No current project. |
| 1001 | (when (not ans) | 1121 | (when (not ans) |
| 1002 | (let* ((ldir (or dir default-directory))) | 1122 | (let* ((ldir (or dir default-directory))) |
| 1003 | (setq ans (ede-directory-get-open-project ldir)) | 1123 | (setq ans (ede-directory-get-open-project ldir)))) |
| 1004 | (or ans | ||
| 1005 | ;; No open project, if this dir pass project-p, then load. | ||
| 1006 | (when (ede-directory-project-p ldir) | ||
| 1007 | (setq ans (ede-load-project-file ldir)))))) | ||
| 1008 | ;; Return what we found. | 1124 | ;; Return what we found. |
| 1009 | ans)) | 1125 | ans)) |
| 1010 | 1126 | ||
| @@ -1059,12 +1175,13 @@ If TARGET belongs to a subproject, return that project file." | |||
| 1059 | "Return the project which is the parent of TARGET. | 1175 | "Return the project which is the parent of TARGET. |
| 1060 | It is recommended you track the project a different way as this function | 1176 | It is recommended you track the project a different way as this function |
| 1061 | could become slow in time." | 1177 | could become slow in time." |
| 1062 | ;; @todo - use ede-object-project as a starting point. | 1178 | (or ede-object-project |
| 1063 | (let ((ans nil) (projs ede-projects)) | 1179 | ;; If not cached, derive it from the current directory of the target. |
| 1064 | (while (and (not ans) projs) | 1180 | (let ((ans nil) (projs ede-projects)) |
| 1065 | (setq ans (ede-target-in-project-p (car projs) target) | 1181 | (while (and (not ans) projs) |
| 1066 | projs (cdr projs))) | 1182 | (setq ans (ede-target-in-project-p (car projs) target) |
| 1067 | ans)) | 1183 | projs (cdr projs))) |
| 1184 | ans))) | ||
| 1068 | 1185 | ||
| 1069 | (defmethod ede-find-target ((proj ede-project) buffer) | 1186 | (defmethod ede-find-target ((proj ede-project) buffer) |
| 1070 | "Fetch the target in PROJ belonging to BUFFER or nil." | 1187 | "Fetch the target in PROJ belonging to BUFFER or nil." |
diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el index 36f902d4e1c..0d84ee41d2c 100644 --- a/lisp/cedet/ede/auto.el +++ b/lisp/cedet/ede/auto.el | |||
| @@ -58,6 +58,13 @@ associated with a single object class, based on the initilizeres used.") | |||
| 58 | :initform t | 58 | :initform t |
| 59 | :documentation | 59 | :documentation |
| 60 | "Non-nil if this is an option when a user creates a project.") | 60 | "Non-nil if this is an option when a user creates a project.") |
| 61 | (safe-p :initarg :safe-p | ||
| 62 | :initform t | ||
| 63 | :documentation | ||
| 64 | "Non-nil if the project load files are \"safe\". | ||
| 65 | An unsafe project is one that loads project variables via Emacs | ||
| 66 | Lisp code. A safe project is one that loads project variables by | ||
| 67 | scanning files without loading Lisp code from them.") | ||
| 61 | ) | 68 | ) |
| 62 | "Class representing minimal knowledge set to run preliminary EDE functions. | 69 | "Class representing minimal knowledge set to run preliminary EDE functions. |
| 63 | When more advanced functionality is needed from a project type, that projects | 70 | When more advanced functionality is needed from a project type, that projects |
| @@ -69,13 +76,15 @@ type is required and the load function used.") | |||
| 69 | :name "Make" :file 'ede/proj | 76 | :name "Make" :file 'ede/proj |
| 70 | :proj-file "Project.ede" | 77 | :proj-file "Project.ede" |
| 71 | :load-type 'ede-proj-load | 78 | :load-type 'ede-proj-load |
| 72 | :class-sym 'ede-proj-project) | 79 | :class-sym 'ede-proj-project |
| 80 | :safe-p nil) | ||
| 73 | (ede-project-autoload "edeproject-automake" | 81 | (ede-project-autoload "edeproject-automake" |
| 74 | :name "Automake" :file 'ede/proj | 82 | :name "Automake" :file 'ede/proj |
| 75 | :proj-file "Project.ede" | 83 | :proj-file "Project.ede" |
| 76 | :initializers '(:makefile-type Makefile.am) | 84 | :initializers '(:makefile-type Makefile.am) |
| 77 | :load-type 'ede-proj-load | 85 | :load-type 'ede-proj-load |
| 78 | :class-sym 'ede-proj-project) | 86 | :class-sym 'ede-proj-project |
| 87 | :safe-p nil) | ||
| 79 | (ede-project-autoload "automake" | 88 | (ede-project-autoload "automake" |
| 80 | :name "automake" :file 'ede/project-am | 89 | :name "automake" :file 'ede/project-am |
| 81 | :proj-file "Makefile.am" | 90 | :proj-file "Makefile.am" |
| @@ -84,6 +93,8 @@ type is required and the load function used.") | |||
| 84 | :new-p nil)) | 93 | :new-p nil)) |
| 85 | "List of vectors defining how to determine what type of projects exist.") | 94 | "List of vectors defining how to determine what type of projects exist.") |
| 86 | 95 | ||
| 96 | (put 'ede-project-class-files 'risky-local-variable t) | ||
| 97 | |||
| 87 | ;;; EDE project-autoload methods | 98 | ;;; EDE project-autoload methods |
| 88 | ;; | 99 | ;; |
| 89 | (defmethod ede-project-root ((this ede-project-autoload)) | 100 | (defmethod ede-project-root ((this ede-project-autoload)) |
| @@ -122,6 +133,19 @@ Return nil if the project file does not exist." | |||
| 122 | (when (and f (file-exists-p f)) | 133 | (when (and f (file-exists-p f)) |
| 123 | f))) | 134 | f))) |
| 124 | 135 | ||
| 136 | (defmethod ede-auto-load-project ((this ede-project-autoload) dir) | ||
| 137 | "Load in the project associated with THIS project autoload description. | ||
| 138 | THIS project description should be valid for DIR, where the project will | ||
| 139 | be loaded." | ||
| 140 | ;; Last line of defense: don't load unsafe projects. | ||
| 141 | (when (not (or (oref this :safe-p) | ||
| 142 | (ede-directory-safe-p dir))) | ||
| 143 | (error "Attempt to load an unsafe project (bug elsewhere in EDE)")) | ||
| 144 | ;; Things are good - so load the project. | ||
| 145 | (let ((o (funcall (oref this load-type) dir))) | ||
| 146 | (when (not o) | ||
| 147 | (error "Project type error: :load-type failed to create a project")) | ||
| 148 | (ede-add-project-to-global-list o))) | ||
| 125 | 149 | ||
| 126 | (provide 'ede/auto) | 150 | (provide 'ede/auto) |
| 127 | 151 | ||
diff --git a/lisp/cedet/ede/simple.el b/lisp/cedet/ede/simple.el index 14b3a043a6d..829c085eade 100644 --- a/lisp/cedet/ede/simple.el +++ b/lisp/cedet/ede/simple.el | |||
| @@ -50,7 +50,8 @@ | |||
| 50 | :name "Simple" :file 'ede/simple | 50 | :name "Simple" :file 'ede/simple |
| 51 | :proj-file 'ede-simple-projectfile-for-dir | 51 | :proj-file 'ede-simple-projectfile-for-dir |
| 52 | :load-type 'ede-simple-load | 52 | :load-type 'ede-simple-load |
| 53 | :class-sym 'ede-simple-project) | 53 | :class-sym 'ede-simple-project |
| 54 | :safe-p nil) | ||
| 54 | t) | 55 | t) |
| 55 | 56 | ||
| 56 | (defcustom ede-simple-save-directory "~/.ede" | 57 | (defcustom ede-simple-save-directory "~/.ede" |