Commit 0c542be0 authored by Vladimir Sedach's avatar Vladimir Sedach

Revised obfuscation facility, added its description to the reference, and added more unit tests.

parent 5e74b5ce
...@@ -1048,7 +1048,7 @@ a-variable => aVariable ...@@ -1048,7 +1048,7 @@ a-variable => aVariable
;;;t \index{namespace} ;;;t \index{namespace}
;;;t \index{PS-PACKAGE-PREFIX} ;;;t \index{PS-PACKAGE-PREFIX}
;;; (setf (PS-PACKAGE-PREFIX lisp-package) string) ; (setf (PS-PACKAGE-PREFIX package-designator) string)
;;; Although JavaScript does not offer namespacing or a package ;;; Although JavaScript does not offer namespacing or a package
;;; system, ParenScript does provide a namespace mechanism for ;;; system, ParenScript does provide a namespace mechanism for
...@@ -1060,17 +1060,38 @@ a-variable => aVariable ...@@ -1060,17 +1060,38 @@ a-variable => aVariable
;;; a particular package receive a prefix when translated to ;;; a particular package receive a prefix when translated to
;;; JavaScript with the `PS-PACKAGE-PREFIX' place. ;;; JavaScript with the `PS-PACKAGE-PREFIX' place.
(lisp (defpackage "MY-LIBRARY" (defpackage "MY-LIBRARY"
(:use #:parenscript)) (:use #:parenscript))
(setf (ps-package-prefix :my-library) "my_library_")) (setf (ps-package-prefix :my-library) "my_library_")
=> 'my_library_'
(defun my-library::library-function (x y) (defun my-library::library-function (x y)
(return (+ x y))) (return (+ x y)))
=> function my_library_libraryFunction(x, y) { -> function my_library_libraryFunction(x, y) {
return x + y; return x + y;
} }
;;;# Identifier obfuscation
;;;t \index{obfuscation}
;;;t \index{identifiers}
;;;t \index{OBFUSCATE-PACKAGE}
;;;t \index{UNOBFUSCATE-PACKAGE}
; (OBFUSCATE-PACKAGE package-designator)
; (UNOBFUSCATE-PACKAGE package-designator)
;;; Similar to the namespace mechanism, ParenScript provides a
;;; facility to generate obfuscated identifiers in certain Lisp
;;; packages.
(defpackage "OBFUSCATE-ME")
(obfuscate-package :obfuscate-me)
(defun obfuscate-me::library-function2 (a b obfuscate-me::foo)
(+ a (my-library::library-function b obfuscate-me::foo)))
;;; The obfuscation and namespace facilities can be used on packages
;;; at the same time.
;;;# The ParenScript Compiler ;;;# The ParenScript Compiler
;;;t \index{compiler} ;;;t \index{compiler}
;;;t \index{ParenScript compiler} ;;;t \index{ParenScript compiler}
......
...@@ -10,19 +10,22 @@ ...@@ -10,19 +10,22 @@
(otherwise (symbol-name symbol)))) (otherwise (symbol-name symbol))))
;;; Symbol obfuscation ;;; Symbol obfuscation
(defvar *obfuscate-identifiers* nil) (defvar *obfuscation-table* (make-hash-table))
(defparameter *obfuscation-table* (make-hash-table)) (defun obfuscate-package (package-designator)
(setf (gethash (find-package package-designator) *obfuscation-table*) (make-hash-table)))
(defun obfuscated-symbol (symbol) (defun unobfuscate-package (package-designator)
(or (gethash symbol *obfuscation-table*) (remhash (find-package package-designator) *obfuscation-table*))
(setf (gethash symbol *obfuscation-table*) (string (gensym)))))
;;; Interface for printing identifiers (defun maybe-obfuscate-symbol (symbol)
(let ((obfuscated-symbol-table (gethash (symbol-package symbol) *obfuscation-table*)))
(if obfuscated-symbol-table
(or (gethash symbol obfuscated-symbol-table)
(setf (gethash symbol obfuscated-symbol-table) (ps-gensym "G")))
symbol)))
(defvar *package-prefix-style* :prefix ;;; Interface for printing identifiers
"Determines how package symbols are serialized to JavaScript identifiers. NIL for
no prefixes. :prefix to prefix variables with something like packagename_identifier.")
(defvar *package-prefix-table* (make-hash-table)) (defvar *package-prefix-table* (make-hash-table))
...@@ -32,8 +35,7 @@ designated package when translating ParenScript code." ...@@ -32,8 +35,7 @@ designated package when translating ParenScript code."
`(gethash (find-package ,package) *package-prefix-table*)) `(gethash (find-package ,package) *package-prefix-table*))
(defun js-translate-symbol (symbol) (defun js-translate-symbol (symbol)
(cond (*obfuscate-identifiers* (obfuscated-symbol symbol)) (let ((possibly-obfuscated-symbol (maybe-obfuscate-symbol symbol)))
((and (eql *package-prefix-style* :prefix) (ps-package-prefix (symbol-package symbol))) (if (ps-package-prefix (symbol-package symbol))
(format nil "~A~A" (ps-package-prefix (symbol-package symbol)) (symbol-to-js symbol))) (format nil "~A~A" (ps-package-prefix (symbol-package symbol)) (symbol-to-js possibly-obfuscated-symbol))
(t (symbol-to-js symbol)))) (symbol-to-js possibly-obfuscated-symbol))))
...@@ -176,9 +176,9 @@ ...@@ -176,9 +176,9 @@
#:*ps-gensym-counter* #:*ps-gensym-counter*
;; naming and namespaces ;; naming and namespaces
#:*obfuscate-identifiers*
#:*package-prefix-style*
#:ps-package-prefix #:ps-package-prefix
#:obfuscate-package
#:unobfuscate-package
;; deprecated interface ;; deprecated interface
#:gen-js-name #:gen-js-name
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
(defvar *ps-gensym-counter* 0) (defvar *ps-gensym-counter* 0)
(defun ps-gensym (&optional (prefix "_js")) (defun ps-gensym (&optional (prefix "_js"))
(make-symbol (format nil "~A-~A" prefix (incf *ps-gensym-counter*)))) (make-symbol (format nil "~A~A" prefix (incf *ps-gensym-counter*))))
(defmacro with-ps-gensyms (symbols &body body) (defmacro with-ps-gensyms (symbols &body body)
"Evaluate BODY with SYMBOLS bound to unique ParenScript identifiers. "Evaluate BODY with SYMBOLS bound to unique ParenScript identifiers.
......
...@@ -5,6 +5,40 @@ ...@@ -5,6 +5,40 @@
(in-suite package-system-tests) (in-suite package-system-tests)
(defpackage "MY-LIBRARY"
(:use #:parenscript))
(setf (ps-package-prefix :my-library) "my_library_")
(test-ps-js lib-function1
(defun my-library::library-function (x y)
(return (+ x y)))
"function my_library_libraryFunction(x, y) {
return x + y;
}")
(defpackage "OBFUSCATE-ME")
(obfuscate-package :obfuscate-me)
(test-ps-js obfuscation1
(defun obfuscate-me::library-function2 (a b obfuscate-me::foo)
(+ a (my-library::library-function b obfuscate-me::foo)))
"function g2(a, b, g3) {
a + my_library_libraryFunction(b, g3);
}")
(defpackage "OBFUSCATE-AND-PREFIX")
(obfuscate-package "OBFUSCATE-AND-PREFIX")
(setf (ps-package-prefix "OBFUSCATE-AND-PREFIX") "__FOO___")
(test-ps-js obfuscate-and-prefix
(defun obfuscate-and-prefix::some-function (a obfuscate-and-prefix::b my-library::d)
(* a
(obfuscate-me::library-function2 obfuscate-and-prefix::b a)
(my-library::library-function my-library::d obfuscate-and-prefix::b)))
"function __FOO___g2(a, __FOO___g3, my_library_d) {
a * g2(__FOO___g3, a) * my_library_libraryFunction(my_library_d, __FOO___g3);
}")
(defpackage "PSTSTPKG" (defpackage "PSTSTPKG"
(:use #:parenscript)) (:use #:parenscript))
......
...@@ -513,16 +513,3 @@ _js2.style.left = _js1;") ...@@ -513,16 +513,3 @@ _js2.style.left = _js1;")
+ ' looks like this.</div>'; + ' looks like this.</div>';
}") }")
(test-ps-js the-parenscript-namespace-system-1
(lisp (defpackage "MY-LIBRARY"
(:use #:parenscript))
(setf (ps-package-prefix :my-library) "my_library_"))
"'my_library_'")
(test-ps-js the-parenscript-namespace-system-2
(defun my-library::library-function (x y)
(return (+ x y)))
"function my_library_libraryFunction(x, y) {
return x + y;
}")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment