diff options
| author | Eric M. Ludlam | 2012-01-13 21:19:25 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-01-13 21:19:25 +0800 |
| commit | 6e9ddbb313cf7db66550f93a74cbba12e39e93c0 (patch) | |
| tree | 75980dee1d1a454da12d6fdd4b377a0e915dad61 | |
| parent | e517eda4d0d6da5d4b8f12be1608fb5e17c455ff (diff) | |
| parent | a62d5ee188dcb532088a15b0a2f066d3305b2eda (diff) | |
| download | emacs-6e9ddbb313cf7db66550f93a74cbba12e39e93c0.tar.gz emacs-6e9ddbb313cf7db66550f93a74cbba12e39e93c0.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 7d6f9f570ec..f9a546ec894 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-12-19 Sam Steingold <sds@gnu.org> | 18 | 2011-12-19 Sam Steingold <sds@gnu.org> |
| 2 | 19 | ||
| 3 | * semantic/edit.el (semantic-edits-incremental-parser): Add the | 20 | * semantic/edit.el (semantic-edits-incremental-parser): Add the |
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el index 5f336df5514..cc8b6f53242 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 | ||
| @@ -420,24 +456,42 @@ provided `global-ede-mode' is enabled." | |||
| 420 | Sets buffer local variables for EDE." | 456 | Sets buffer local variables for EDE." |
| 421 | (let* ((ROOT nil) | 457 | (let* ((ROOT nil) |
| 422 | (proj (ede-directory-get-open-project default-directory | 458 | (proj (ede-directory-get-open-project default-directory |
| 423 | 'ROOT))) | 459 | 'ROOT)) |
| 460 | (projauto nil)) | ||
| 461 | |||
| 424 | (when (or proj ROOT | 462 | (when (or proj ROOT |
| 425 | (ede-directory-project-p default-directory t)) | 463 | ;; If there is no open project, look up the project |
| 464 | ;; autoloader to see if we should initialize. | ||
| 465 | (setq projauto (ede-directory-project-p default-directory t))) | ||
| 466 | |||
| 467 | (when (and (not proj) projauto) | ||
| 468 | |||
| 469 | ;; No project was loaded, but we have a project description | ||
| 470 | ;; object. This means that we can check if it is a safe | ||
| 471 | ;; project to load before requesting it to be loaded. | ||
| 426 | 472 | ||
| 427 | (when (not proj) | 473 | (when (or (oref projauto safe-p) |
| 428 | ;; @todo - this could be wasteful. | 474 | ;; The project style is not safe, so check if it is |
| 429 | (setq proj (ede-load-project-file default-directory 'ROOT))) | 475 | ;; in `ede-project-directories'. |
| 476 | (let ((top (ede-toplevel-project default-directory))) | ||
| 477 | (ede-directory-safe-p top))) | ||
| 430 | 478 | ||
| 431 | (setq ede-object (ede-buffer-object (current-buffer) | 479 | ;; The project is safe, so load it in. |
| 480 | (setq proj (ede-load-project-file default-directory 'ROOT)))) | ||
| 481 | |||
| 482 | ;; Only initialize EDE state in this buffer if we found a project. | ||
| 483 | (when proj | ||
| 484 | |||
| 485 | (setq ede-object (ede-buffer-object (current-buffer) | ||
| 432 | 'ede-object-project)) | 486 | 'ede-object-project)) |
| 433 | 487 | ||
| 434 | (setq ede-object-root-project | 488 | (setq ede-object-root-project |
| 435 | (or ROOT (ede-project-root ede-object-project))) | 489 | (or ROOT (ede-project-root ede-object-project))) |
| 436 | 490 | ||
| 437 | (if (and (not ede-object) ede-object-project) | 491 | (if (and (not ede-object) ede-object-project) |
| 438 | (ede-auto-add-to-target)) | 492 | (ede-auto-add-to-target)) |
| 439 | 493 | ||
| 440 | (ede-apply-target-options)))) | 494 | (ede-apply-target-options))))) |
| 441 | 495 | ||
| 442 | (defun ede-reset-all-buffers (onoff) | 496 | (defun ede-reset-all-buffers (onoff) |
| 443 | "Reset all the buffers due to change in EDE. | 497 | "Reset all the buffers due to change in EDE. |
| @@ -557,13 +611,73 @@ of objects with the `ede-want-file-p' method." | |||
| 557 | 611 | ||
| 558 | ;;; Interactive method invocations | 612 | ;;; Interactive method invocations |
| 559 | ;; | 613 | ;; |
| 560 | (defun ede (file) | 614 | (defun ede (dir) |
| 561 | "Start up EDE on something. | 615 | "Start up EDE for directory DIR. |
| 562 | Argument FILE is the file or directory to load a project from." | 616 | If DIR has an existing project file, load it. |
| 563 | (interactive "fProject File: ") | 617 | Otherwise, create a new project for DIR." |
| 564 | (if (not (file-exists-p file)) | 618 | (interactive |
| 565 | (ede-new file) | 619 | ;; When choosing a directory to turn on, and we see some directory here, |
| 566 | (ede-load-project-file (file-name-directory file)))) | 620 | ;; provide that as the default. |
| 621 | (let* ((top (ede-toplevel-project default-directory)) | ||
| 622 | (promptdflt (or top default-directory))) | ||
| 623 | (list (read-directory-name "Project directory: " | ||
| 624 | promptdflt promptdflt t)))) | ||
| 625 | (unless (file-directory-p dir) | ||
| 626 | (error "%s is not a directory" dir)) | ||
| 627 | (when (ede-directory-get-open-project dir) | ||
| 628 | (error "%s already has an open project associated with it" dir)) | ||
| 629 | |||
| 630 | ;; Check if the directory has been added to the list of safe | ||
| 631 | ;; directories. It can also add the directory to the safe list if | ||
| 632 | ;; the user chooses. | ||
| 633 | (if (ede-check-project-directory dir) | ||
| 634 | (progn | ||
| 635 | ;; If there is a project in DIR, load it, otherwise do | ||
| 636 | ;; nothing. | ||
| 637 | (ede-load-project-file dir) | ||
| 638 | |||
| 639 | ;; Check if we loaded anything on the previous line. | ||
| 640 | (if (ede-current-project dir) | ||
| 641 | |||
| 642 | ;; We successfully opened an existing project. Some open | ||
| 643 | ;; buffers may also be referring to this project. | ||
| 644 | ;; Resetting all the buffers will get them to also point | ||
| 645 | ;; at this new open project. | ||
| 646 | (ede-reset-all-buffers 1) | ||
| 647 | |||
| 648 | ;; ELSE | ||
| 649 | ;; There was no project, so switch to `ede-new' which is how | ||
| 650 | ;; a user can select a new kind of project to create. | ||
| 651 | (let ((default-directory (expand-file-name dir))) | ||
| 652 | (call-interactively 'ede-new)))) | ||
| 653 | |||
| 654 | ;; If the proposed directory isn't safe, then say so. | ||
| 655 | (error "%s is not an allowed project directory in `ede-project-directories'" | ||
| 656 | dir))) | ||
| 657 | |||
| 658 | (defun ede-check-project-directory (dir) | ||
| 659 | "Check if DIR should be in `ede-project-directories'. | ||
| 660 | If it is not, try asking the user if it should be added; if so, | ||
| 661 | add it and save `ede-project-directories' via Customize. | ||
| 662 | Return nil iff DIR should not be in `ede-project-directories'." | ||
| 663 | (setq dir (directory-file-name (expand-file-name dir))) ; strip trailing / | ||
| 664 | (or (eq ede-project-directories t) | ||
| 665 | (and (functionp ede-project-directories) | ||
| 666 | (funcall ede-project-directories dir)) | ||
| 667 | ;; If `ede-project-directories' is a list, maybe add it. | ||
| 668 | (when (listp ede-project-directories) | ||
| 669 | (or (member dir ede-project-directories) | ||
| 670 | (when (y-or-n-p (format "`%s' is not listed in `ede-project-directories'. | ||
| 671 | Add it to the list of allowed project directories? " | ||
| 672 | dir)) | ||
| 673 | (push dir ede-project-directories) | ||
| 674 | ;; If possible, save `ede-project-directories'. | ||
| 675 | (if (or custom-file user-init-file) | ||
| 676 | (let ((coding-system-for-read nil)) | ||
| 677 | (customize-save-variable | ||
| 678 | 'ede-project-directories | ||
| 679 | ede-project-directories))) | ||
| 680 | t))))) | ||
| 567 | 681 | ||
| 568 | (defun ede-new (type &optional name) | 682 | (defun ede-new (type &optional name) |
| 569 | "Create a new project starting from project type TYPE. | 683 | "Create a new project starting from project type TYPE. |
| @@ -598,6 +712,11 @@ Optional argument NAME is the name to give this project." | |||
| 598 | (error "Cannot create project in non-existent directory %s" default-directory)) | 712 | (error "Cannot create project in non-existent directory %s" default-directory)) |
| 599 | (when (not (file-writable-p default-directory)) | 713 | (when (not (file-writable-p default-directory)) |
| 600 | (error "No write permissions for %s" default-directory)) | 714 | (error "No write permissions for %s" default-directory)) |
| 715 | (unless (ede-check-project-directory default-directory) | ||
| 716 | (error "%s is not an allowed project directory in `ede-project-directories'" | ||
| 717 | default-directory)) | ||
| 718 | ;; Make sure the project directory is loadable in the future. | ||
| 719 | (ede-check-project-directory default-directory) | ||
| 601 | ;; Create the project | 720 | ;; Create the project |
| 602 | (let* ((obj (object-assoc type 'name ede-project-class-files)) | 721 | (let* ((obj (object-assoc type 'name ede-project-class-files)) |
| 603 | (nobj (let ((f (oref obj file)) | 722 | (nobj (let ((f (oref obj file)) |
| @@ -631,6 +750,10 @@ Optional argument NAME is the name to give this project." | |||
| 631 | (ede-add-subproject pp nobj) | 750 | (ede-add-subproject pp nobj) |
| 632 | (ede-commit-project pp))) | 751 | (ede-commit-project pp))) |
| 633 | (ede-commit-project nobj)) | 752 | (ede-commit-project nobj)) |
| 753 | ;; Once the project is created, load it again. This used to happen | ||
| 754 | ;; lazily, but with project loading occurring less often and with | ||
| 755 | ;; security in mind, this is now the safe time to reload. | ||
| 756 | (ede-load-project-file default-directory) | ||
| 634 | ;; Have the menu appear | 757 | ;; Have the menu appear |
| 635 | (setq ede-minor-mode t) | 758 | (setq ede-minor-mode t) |
| 636 | ;; Allert the user | 759 | ;; Allert the user |
| @@ -653,11 +776,16 @@ ARGS are additional arguments to pass to method SYM." | |||
| 653 | (defun ede-rescan-toplevel () | 776 | (defun ede-rescan-toplevel () |
| 654 | "Rescan all project files." | 777 | "Rescan all project files." |
| 655 | (interactive) | 778 | (interactive) |
| 656 | (let ((toppath (ede-toplevel-project default-directory)) | 779 | (if (not (ede-directory-get-open-project default-directory)) |
| 657 | (ede-deep-rescan t)) | 780 | ;; This directory isn't open. Can't rescan. |
| 658 | (project-rescan (ede-load-project-file toppath)) | 781 | (error "Attempt to rescan a project that isn't open") |
| 659 | (ede-reset-all-buffers 1) | 782 | |
| 660 | )) | 783 | ;; Continue |
| 784 | (let ((toppath (ede-toplevel-project default-directory)) | ||
| 785 | (ede-deep-rescan t)) | ||
| 786 | |||
| 787 | (project-rescan (ede-load-project-file toppath)) | ||
| 788 | (ede-reset-all-buffers 1)))) | ||
| 661 | 789 | ||
| 662 | (defun ede-new-target (&rest args) | 790 | (defun ede-new-target (&rest args) |
| 663 | "Create a new target specific to this type of project file. | 791 | "Create a new target specific to this type of project file. |
| @@ -893,7 +1021,7 @@ Optional ROOTRETURN will return the root project for DIR." | |||
| 893 | ;; Do the load | 1021 | ;; Do the load |
| 894 | ;;(message "EDE LOAD : %S" file) | 1022 | ;;(message "EDE LOAD : %S" file) |
| 895 | (let* ((file dir) | 1023 | (let* ((file dir) |
| 896 | (path (expand-file-name (file-name-directory file))) | 1024 | (path (file-name-as-directory (expand-file-name dir))) |
| 897 | (pfc (ede-directory-project-p path)) | 1025 | (pfc (ede-directory-project-p path)) |
| 898 | (toppath nil) | 1026 | (toppath nil) |
| 899 | (o nil)) | 1027 | (o nil)) |
| @@ -922,13 +1050,11 @@ Optional ROOTRETURN will return the root project for DIR." | |||
| 922 | ;; See if it's been loaded before | 1050 | ;; See if it's been loaded before |
| 923 | (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file | 1051 | (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file |
| 924 | ede-projects)) | 1052 | ede-projects)) |
| 925 | (if (not o) | 1053 | |
| 926 | ;; If not, get it now. | 1054 | ;; If not open yet, load it. |
| 927 | (let ((ede-constructing pfc)) | 1055 | (unless o |
| 928 | (setq o (funcall (oref pfc load-type) toppath)) | 1056 | (let ((ede-constructing pfc)) |
| 929 | (when (not o) | 1057 | (setq o (ede-auto-load-project pfc toppath)))) |
| 930 | (error "Project type error: :load-type failed to create a project")) | ||
| 931 | (ede-add-project-to-global-list o))) | ||
| 932 | 1058 | ||
| 933 | ;; Return the found root project. | 1059 | ;; Return the found root project. |
| 934 | (when rootreturn (set rootreturn o)) | 1060 | (when rootreturn (set rootreturn o)) |
| @@ -982,13 +1108,7 @@ Optional argument OBJ is an object to find the parent of." | |||
| 982 | (and root | 1108 | (and root |
| 983 | (ede-find-subproject-for-directory root updir)) | 1109 | (ede-find-subproject-for-directory root updir)) |
| 984 | ;; Try the all structure based search. | 1110 | ;; Try the all structure based search. |
| 985 | (ede-directory-get-open-project updir) | 1111 | (ede-directory-get-open-project updir)))))))) |
| 986 | ;; Load up the project file as a last resort. | ||
| 987 | ;; Last resort since it uses file-truename, and other | ||
| 988 | ;; slow features. | ||
| 989 | (and (ede-directory-project-p updir) | ||
| 990 | (ede-load-project-file | ||
| 991 | (file-name-as-directory updir)))))))))) | ||
| 992 | 1112 | ||
| 993 | (defun ede-current-project (&optional dir) | 1113 | (defun ede-current-project (&optional dir) |
| 994 | "Return the current project file. | 1114 | "Return the current project file. |
| @@ -1002,11 +1122,7 @@ If optional DIR is provided, get the project for DIR instead." | |||
| 1002 | ;; No current project. | 1122 | ;; No current project. |
| 1003 | (when (not ans) | 1123 | (when (not ans) |
| 1004 | (let* ((ldir (or dir default-directory))) | 1124 | (let* ((ldir (or dir default-directory))) |
| 1005 | (setq ans (ede-directory-get-open-project ldir)) | 1125 | (setq ans (ede-directory-get-open-project ldir)))) |
| 1006 | (or ans | ||
| 1007 | ;; No open project, if this dir pass project-p, then load. | ||
| 1008 | (when (ede-directory-project-p ldir) | ||
| 1009 | (setq ans (ede-load-project-file ldir)))))) | ||
| 1010 | ;; Return what we found. | 1126 | ;; Return what we found. |
| 1011 | ans)) | 1127 | ans)) |
| 1012 | 1128 | ||
| @@ -1061,12 +1177,13 @@ If TARGET belongs to a subproject, return that project file." | |||
| 1061 | "Return the project which is the parent of TARGET. | 1177 | "Return the project which is the parent of TARGET. |
| 1062 | It is recommended you track the project a different way as this function | 1178 | It is recommended you track the project a different way as this function |
| 1063 | could become slow in time." | 1179 | could become slow in time." |
| 1064 | ;; @todo - use ede-object-project as a starting point. | 1180 | (or ede-object-project |
| 1065 | (let ((ans nil) (projs ede-projects)) | 1181 | ;; If not cached, derive it from the current directory of the target. |
| 1066 | (while (and (not ans) projs) | 1182 | (let ((ans nil) (projs ede-projects)) |
| 1067 | (setq ans (ede-target-in-project-p (car projs) target) | 1183 | (while (and (not ans) projs) |
| 1068 | projs (cdr projs))) | 1184 | (setq ans (ede-target-in-project-p (car projs) target) |
| 1069 | ans)) | 1185 | projs (cdr projs))) |
| 1186 | ans))) | ||
| 1070 | 1187 | ||
| 1071 | (defmethod ede-find-target ((proj ede-project) buffer) | 1188 | (defmethod ede-find-target ((proj ede-project) buffer) |
| 1072 | "Fetch the target in PROJ belonging to BUFFER or nil." | 1189 | "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 7ff291d3675..b458cc246f0 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 initializers 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 028c126e9e4..5cfa750c63f 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" |