From 1ca6369721eeadded29fc538b996267ff88a38b9 Mon Sep 17 00:00:00 2001 From: Aaron Ecay Date: Mon, 28 Oct 2013 15:39:31 -0400 Subject: [PATCH 2/3] Mark some org-babel variables as safe locals under proper conditions * lisp/ob-core.el (org-babel-inline-result-wrap, org-babel-default-header-args, org-babel-default-inline-header-args): mark as safe local variables --- lisp/ob-core.el | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ testing/lisp/test-ob.el | 21 +++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/lisp/ob-core.el b/lisp/ob-core.el index 8fafd4b..b1a6871 100644 --- a/lisp/ob-core.el +++ b/lisp/ob-core.el @@ -158,6 +158,11 @@ See also `org-babel-noweb-wrap-start'." This string must include a \"%s\" which will be replaced by the results." :group 'org-babel :type 'string) +(put 'org-babel-inline-result-wrap + 'safe-local-variable + (lambda (value) + (and (stringp value) + (string-match-p "%s" value)))) (defun org-babel-noweb-wrap (&optional regexp) (concat org-babel-noweb-wrap-start @@ -484,10 +489,14 @@ specific header arguments as well.") '((:session . "none") (:results . "replace") (:exports . "code") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no")) "Default arguments to use when evaluating a source block.") +(put 'org-babel-default-header-args 'safe-local-variable + (org-babel-header-args-safe-fn org-babel-safe-header-args)) (defvar org-babel-default-inline-header-args '((:session . "none") (:results . "replace") (:exports . "results")) "Default arguments to use when evaluating an inline source block.") +(put 'org-babel-default-inline-header-args 'safe-local-variable + (org-babel-header-args-safe-fn org-babel-safe-header-args)) (defvar org-babel-data-names '("tblname" "results" "name")) @@ -2785,6 +2794,60 @@ of `org-babel-temporary-directory'." (add-hook 'kill-emacs-hook 'org-babel-remove-temporary-directory) +(defconst org-babel-safe-header-args + '(:cache :colnames :comments :exports :epilogue :hlines :noeval + :noweb :noweb-ref :noweb-sep :padline :prologue :rownames + :sep :session :tangle :wrap + (:eval . ("never" "query")) + (:results . (lambda (str) (not (string-match "file" str))))) + "A list of safe header arguments for babel source blocks. + +The list can have entries of the following forms: +- :ARG -> :ARG is always a safe header arg +- (:ARG . (VAL1 VAL2 ...)) -> :ARG is safe as a header arg if it is + `equal' to one of the VALs. +- (:ARG . FN) -> :ARG is safe as a header arg if the function FN + returns non-nil. FN is passed one + argument, the value of the header arg + (as a string).") + +(defun org-babel-one-header-arg-safe-p (pair safe-list) + "Determine if the PAIR is a safe babel header arg according to SAFE-LIST. + +For the format of SAFE-LIST, see `org-babel-safe-header-args'." + (and (consp pair) + (keywordp (car pair)) + (stringp (cdr pair)) + (or + (memq (car pair) safe-list) + (let ((entry (assq (car pair) safe-list))) + (and entry + (consp entry) + (cond ((functionp (cdr entry)) + (funcall (cdr entry) (cdr pair))) + ((listp (cdr entry)) + (member (cdr pair) (cdr entry))) + (t nil))))))) + +(defmacro org-babel-header-args-safe-fn (safe-list) + "Return a function that determines whether a list of header args are safe. + +Intended usage is: +\(put 'org-babel-default-header-args 'safe-local-variable + (org-babel-header-args-safe-p org-babel-safe-header-args) + +This allows org-babel languages to extend the list of safe values for +their `org-babel-default-header-args:foo' variable. + +For the format of SAFE-LIST, see `org-babel-safe-header-args'." + `(lambda (value) + (and (listp value) + (org-every + (lambda (pair) + (and (consp pair) + (org-babel-one-header-arg-safe-p pair ,safe-list))) + value)))) + (provide 'ob-core) ;; Local variables: diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el index 93c026b..e7f0645 100644 --- a/testing/lisp/test-ob.el +++ b/testing/lisp/test-ob.el @@ -1181,6 +1181,27 @@ echo \"$data\" (list (org-get-indentation) (progn (forward-line) (org-get-indentation))))))) +(ert-deftest test-ob/safe-header-args () + "Detect safe and unsafe header args." + (let ((safe-args '((:cache . "foo") + (:results . "output") + (:eval . "never") + (:eval . "query"))) + (unsafe-args '((:eval . "yes") + (:results . "output file") + (:foo . "bar"))) + (malformed-args '((bar . "foo") + ("foo" . "bar") + :foo)) + (safe-p (org-babel-header-args-safe-fn org-babel-safe-header-args))) + (dolist (arg safe-args) + (should (org-babel-one-header-arg-safe-p arg org-babel-safe-header-args))) + (dolist (arg unsafe-args) + (should (not (org-babel-one-header-arg-safe-p arg org-babel-safe-header-args)))) + (dolist (arg malformed-args) + (should (not (org-babel-one-header-arg-safe-p arg org-babel-safe-header-args)))) + (should (not (funcall safe-p (append safe-args unsafe-args)))))) + (provide 'test-ob) ;;; test-ob ends here -- 1.8.4.2