summaryrefslogtreecommitdiff
path: root/elisp/erbot/erblisp.el
diff options
context:
space:
mode:
Diffstat (limited to 'elisp/erbot/erblisp.el')
-rw-r--r--elisp/erbot/erblisp.el276
1 files changed, 276 insertions, 0 deletions
diff --git a/elisp/erbot/erblisp.el b/elisp/erbot/erblisp.el
new file mode 100644
index 0000000..6530b94
--- /dev/null
+++ b/elisp/erbot/erblisp.el
@@ -0,0 +1,276 @@
+;;; erblisp.el ---
+;; Time-stamp: <2007-11-23 11:30:08 deego>
+;; Copyright (C) 2002 D. Goel
+;; Emacs Lisp Archive entry
+;; Filename: erblisp.el
+;; Package: erblisp
+;; Author: D. Goel <deego@gnufans.org>
+;; Version: 0.0DEV
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErBot
+
+
+
+;; This file is NOT (yet) part of GNU Emacs.
+
+;; This is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+
+;; See also:
+
+
+(defvar erblisp-version "0.0dev")
+
+;;==========================================
+;;; Code:
+
+(defgroup erblisp nil
+ "The group erblisp"
+ :group 'applications)
+(defcustom erblisp-before-load-hooks nil "" :group 'erblisp)
+(defcustom erblisp-after-load-hooks nil "" :group 'erblisp)
+(run-hooks 'erblisp-before-load-hooks)
+
+
+(defun erblisp-process-msg (msg &optional proc nick tgt)
+ "MSG is either a string or a tree.. If it is a tree, it looks
+something like
+ '(foo bar (bar foo))
+
+This command sandboxes the message and then processes it.."
+
+ (if (stringp msg)
+ (setq msg (erbn-read msg)))
+ (format "%s" (eval (erblisp-sandbox-fuzzy msg))))
+
+(defun erblisp-sandbox-quoted-maybe (expr)
+ "sandboxes the whole expression even if it starts with a quote."
+ (cond
+ ((and (listp expr)
+ (equal (first expr) 'quote))
+ (cons 'quote
+ (mapcar 'erblisp-sandbox (cdr expr))))
+ (t (erblisp-sandbox expr))))
+
+
+(defun erblisp-sandbox-quoted (expr)
+ "Assumes that the expression will result in a quoted thingy and
+tries to make sure that we sandbox that whole quoted thing.. "
+ (cond
+ ((and (listp expr)
+ (equal (first expr) 'quote))
+ (cons 'quote
+ (mapcar 'erblisp-sandbox (cdr expr))))
+ ((listp expr)
+ (list 'erblisp-sandbox-quoted (erblisp-sandbox expr)))
+ ;; just an atom
+ (t (erblisp-sandbox expr))))
+
+
+(defvar erblisp-allowed-words
+ '(nil t
+ ;; Also consider:
+ ;; &rest
+ ;; &optional
+
+ )
+ "You should add &rest and &optional to this list.
+We WON'T do this by default since this could lead to exploits if you
+*happen* to have bound these keywords to weird stuff like
+\(setq &rest (shell-command \"rm -rf /\")) in your .emacs."
+)
+
+(defvar erblisp-max-list-length 2000
+ "If non-numeric, we will skip this check."
+ )
+
+(defun erblisp-safe-length-args-p (list so-far len)
+ (let ((cur list)
+ stack)
+ (while (and cur
+ (<= so-far len))
+ (if (consp (car cur))
+ (progn (setq cur (car cur))
+ (when (consp (cdr cur))
+ (push (cdr cur) stack)))
+ (setq cur (cdr cur)))
+ (unless cur
+ (setq cur (pop stack)))
+ (setq so-far (1+ so-far)))
+ (if (<= so-far len)
+ t
+ nil)))
+
+(defmacro erblisp-check-args (&rest args)
+ "All we do in this macro we remove some bindings for things like
+&rest, etc, things that do not have values but got passed to us --
+this occurs when a user attempts to use &rest in his function
+definitions -- see `erblisp-allowed-words'.
+
+All the arguments to this macro should have been in their evalled form
+and hence constants already, so we do not bother protecting against
+multiple evaluations here -- evaluating a constant causes no harm.
+All we do in this macro we remove some bindings for things like &rest,
+etc, things that are not defined, but passed on here in any case."
+ `(erblisp-check-args-nascent
+ ,@(remove-if
+ #'(lambda (arg) (and
+ (symbolp arg)
+ (not (boundp arg))))
+ args)))
+
+
+
+(defun erblisp-check-args-nascent (&rest args)
+ (if (or
+ (not (numberp erblisp-max-list-length))
+ (erblisp-safe-length-args-p args 0 erblisp-max-list-length))
+ t
+ (error "encountered overlong expression, ignoring") nil))
+
+
+
+
+(defun erblisp-sandbox (expr)
+ ""
+ (cond
+ ;; first condition
+ ((null expr) nil)
+ ;; second condition
+ ((listp expr)
+ (when (erblisp-check-args expr)
+ (let ((fir (first expr)))
+ (cond
+ ((listp fir)
+ (cons (erblisp-sandbox fir)
+ (mapcar 'erblisp-sandbox (cdr expr))))
+ ((equal (format "%S" fir) "quote")
+ ;; if quoted, it is fine...
+ expr)
+ (t (cons
+ (if (or (equal 0 (string-match "fs-" (format "%S" fir)))
+ (member fir erblisp-allowed-words))
+ fir
+ (intern (concat "fs-" (format "%S" fir))))
+ (mapcar 'erblisp-sandbox (cdr expr))))))))
+
+ ;; final condition.. --> when the expr is an atom.. It should be a
+ ;; a constant.. or an allowed atom.. allowed == prefixed with fs-
+ (t (cond
+ ((and (symbolp expr)
+ (equal 0 (string-match "fs-" (format "%s" expr))))
+ expr)
+ ((equal expr t) expr)
+ ((member expr erblisp-allowed-words) expr)
+ ((symbolp expr)
+ ;;(boundp (intern (concat "fs-" (format "%S" expr)))))
+ (intern (concat "fs-" (format "%s" expr))))
+ ;; other symbol
+ ;;((symbolp expr) (list 'quote expr))
+ ;; a number or string now..
+ ;; this actually happens when they feed byte-compiled code to
+ ;; the bot, like:
+ ;;, (funcall #[nil "\300\207" [1] 1])
+ ((not (or (symbolp expr) (numberp expr) (stringp expr)))
+ (error "%s %s" "Should not reach here. Quantum Tunnelling! "
+ "What are you trying to feed me? Byte-compiled code? Vectors?" ))
+ (t expr)))
+ ))
+
+(defun erblisp-sandbox-fuzzy (expr)
+ "Sandboxes a message.. Ensures that the functions are all fs-
+and the arguments are NOT variable-names... This one sandboxes
+preferably by quoting unless fs-symbol is bound.."
+ (cond
+
+ ;; first condition
+ ((null expr) nil)
+
+ ;; second condition
+ ((listp expr)
+ (let ((fir (first expr)))
+ (cond
+ ((listp fir)
+ (cons (erblisp-sandbox-fuzzy fir))
+ (mapcar 'erblisp-sandbox-fuzzy (cdr expr)))
+ ((equal (format "%S" fir) "quote")
+ ;; if quoted, it is fine...
+ expr)
+ (t (cons
+ (if (equal 0 (string-match "fs-" (format "%S" fir)))
+ fir
+ (intern (concat "fs-" (format "%S" fir))))
+ (mapcar 'erblisp-sandbox-fuzzy (cdr expr)))))))
+
+
+ ;; final condition.. --> when the expr is an atom.. It should be a
+ ;; a constant.. or an allowed atom.. allowed == prefixed with fs-
+ (t (cond
+ ((and (symbolp expr)
+ (equal 0 (string-match "fs-" (format "%s" expr))))
+ expr)
+ ((and (symbolp expr)
+ (or
+ (boundp (intern (concat "fs-" (format "%S" expr))))
+ (fboundp (intern (concat "fs-" (format "%S" expr))))
+ ))
+ (intern (concat "fs-" (format "%s" expr))))
+ ;; other symbol
+ ((symbolp expr) (list 'quote expr))
+ ;; a number or string now..
+
+ ((not (or (symbolp expr) (numberp expr) (stringp expr)))
+ (error "Should not reach here. Fuzzy tunnels!"))
+ (t expr)))
+ ))
+
+
+
+
+(defun erblisp-sandbox-full(expr &optional midstream)
+ "
+This will ensure that anything rigt after parens is sandboxed by a
+fs- prefix. And anything else is either a symbol , or a string,
+but not a variable... viz: quoted ...else converted into one.
+
+midstream is in internal variable..."
+ (cond
+ ((null expr) nil)
+ ((listp expr)
+ (let* ((fir (first expr)))
+ (if (eql fir 'quote)
+ expr
+ (cons (erblisp-sandbox-full fir)
+ (mapcar '(lambda (arg)
+ (erblisp-sandbox-full arg t))
+ (cdr expr))))))
+ ;; now we know that expr is a non-nil atom...
+ (midstream
+ (if (stringp expr) expr
+ (list 'quote expr)))
+
+
+
+ ;; midstream is untrue... expr is thus an atom at the beginning..
+ (t
+ (if (equal 0 (string-match "fs-" (format "%s" expr)))
+ expr (intern (concat "fs-" (format "%s" expr)))))))
+
+(provide 'erblisp)
+(run-hooks 'erblisp-after-load-hooks)
+
+
+
+;;; erblisp.el ends here