[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SES local variables to define printers

From: Vincent Belaïche
Subject: SES local variables to define printers
Date: Thu, 23 May 2013 22:52:07 +0200


I have come across a ``regression'' in SES --- well I am not sure that
one can call it a ``regression'', let us rather say that one year ago it
was possible to play some borderline trick which is now no longer
possible with a recent EMACS.

That sort of trick was to define a file local variable foo to a lambda
expression defining a printer function, and then use the foo symbol as a
printer when setting the printer for a cell.

I wrote that this is a ``borderline trick'' because when you do that you
set the symbol-value of foo to the printer, and not its
symbol-function. But that was working --- I don't know why.

By the way, that kind of things was a security breach because you allow
to call a function defined in the file without any control. I suspect
that the root cause why this is no longer working is that EMACS has been
made more secure on that respect --- sorry I am not a regular lurker of
what is going on on this forum, so indeed I have no idea.

Now, I would like to have again the same sort of feature in SES, so I
did a quick hack herein attached --- there is a defcustom, so that the
user who re-enables this, does it at his/her own perils. But I am not
really satisfied with that patch --- so I did not commit it --- because
I think I should do more security checks if possible on the printer
function that is defined as a buffer local lambda expression.

So, I have a few questions to you experts:

- is that possible to check that a function do no border effect, like a
  SES printer function should do --- well, I presume, at least for
  buffer locally defined function --- anyway I would create some
  defcustom to deactivate that security check.

- is that possible to check that when a function is executing, that
  takes a reasonable time, and if not to interact with the use and ask
  whether he/she would like to double that time


=== modified file 'lisp/ses.el'
--- lisp/ses.el 2013-01-02 16:13:04 +0000
+++ lisp/ses.el 2013-05-22 16:09:39 +0000
@@ -100,6 +100,26 @@
   :group 'ses
   :type 'hook)
+(defcustom ses-enable-local-variables nil
+  "Non-nil if SES should process local-variables lists in ses buffers.
+\(You can explicitly request processing the local-variables by
+executing `(hack-local-variables)'). Local variables are useful
+to define file local printers or values but raise a security
+issue if the printer function is used to do border effects. If
+you select `Filename test', then you should configure a function
+symbol or lambda expression which takes one argument, then the
+local variables are processed iff the buffer file name passed to
+this function returns a non nil. For instance you could configure:
+  (lambda (x)
+    (string-match \"^/dir/where/local/var/are/allowed\" 
+                 (expand-file-name x)))
+  :type '(choice
+         (const :tag "No" nil)
+         (const :tag "Yes" t)
+         (function :tag "Filename test"))
+  :group 'ses)
 ;; Global variables and constants
@@ -661,9 +681,11 @@
 (defun ses-printer-validate (printer)
   "Signal an error if PRINTER is not a valid SES cell printer."
   (or (not printer)
       (stringp printer)
       (functionp printer)
+      (and (symbolp printer) (boundp printer) (functionp (symbol-value 
       (and (stringp (car-safe printer)) (not (cdr printer)))
       (error "Invalid printer function"))
@@ -1261,6 +1283,10 @@
            (format (car printer) value)
+       (and (symbolp printer)
+            (boundp printer)
+            (functionp (symbol-value printer))
+            (setq printer (symbol-value printer)))
        (setq value (funcall printer (or value "")))
        (if (stringp value)
@@ -1899,9 +1925,17 @@
   (unless (and (boundp 'ses--deferred-narrow)
               (eq ses--deferred-narrow 'ses-mode))
+    (setq major-mode 'ses-mode)
+    (and
+     enable-local-variables
+     ses-enable-local-variables
+     (or (eq ses-enable-local-variables t)
+        (let ((bfn (buffer-file-name)))
+          (and (stringp bfn)
+               (funcall ses-enable-local-variables bfn))))
+     (hack-local-variables))
-    (setq major-mode             'ses-mode
-         mode-name              "SES"
+    (setq mode-name              "SES"
          next-line-add-newlines nil
          truncate-lines         t
          ;; SES deliberately puts lots of trailing whitespace in its buffer.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]