Call: +44 (0)1904 557620 Call
Blog

Pete Finnigan's Oracle Security Weblog

This is the weblog for Pete Finnigan. Pete works in the area of Oracle security and he specialises in auditing Oracle databases for security issues. This weblog is aimed squarely at those interested in the security of their Oracle databases.

[Previous entry: "Can We Remove IF Statements from PL/SQL?"] [Next entry: "Searching Base64 Encoded text for a clear text string"]

Write An Interpreter in PL/SQL - Adding More Features

Just a short post about the PL/SQL parser and interpreter that I have been developing.

As I have said in recent posts I am going to release a set of articles about the development of this interpreter in PL/SQL. I have over 120 pages of written notes and examples so far. As I said in the last post I will decide how to release these, either as about 15 - 25 blog posts or as articles indexed on my site; so not in the actual blog software but essentially the same; I may also release all of the notes as a short e-book on this website; not sure yet.

Of course, there are still features to add to the language and also to the interpreter and also to decide whether to convert it and also implement a compiler for the language and assembler and a CPU VM...

I have extended the language now so that it also has IF/ELSE/FI and also LOOP/EXIT/POOL keywords; so whist it can still support simple BASIC like syntax and GOTO and LABELs etc it is now easier to write programs without worrying about those GOTO and LABELs. The LABELs are now alpha as well so not :30 or :10 as in the previous examples. Also unlike BASIC we don't have a formal line structured program with a line number per line. We can also free form and indent the program structure as you will see in my examples.

I just wanted to show a quick couple of examples that tests IF statements and also the LOOP and EXIT statements. Here is a sample that tests and IF statement and a second that tests an IF/ELSE statement and a simple LOOP including an EXIT keyword.

Here is the simple example:

declare
lv_prog varchar2(32767):=q'[
LET m=20
LET x=1
LET y=1
IF x PRINT "x This should print "
PRINT "x---------------------"
FI
IF y>m THEN
PRINT "y This should not print"
PRINT "y----------------------"
FI
IF x PRINT "x1 This should print"
PRINT "x1---------------------"
ELSE
PRINT "x2 This should not print"
PRINT "x2---------------------"
FI
IF y>m THEN
PRINT "y1 This should not print"
PRINT "y1---------------------"
ELSE
PRINT "y2 This should print"
PRINT "y2---------------------"
FI
LET m=2
LET x=1
PRINT "Start of tests"
PRINT "=================="
LOOP
PRINT "x is [";x;"]"
IF x>m THEN
EXIT
FI
LET x=x+1
POOL
PRINT "End of Tests"
END
]';
begin
--
pfclscript.init(true,1);
pfclscript.run(lv_prog);
--
end;
/

And running this gives:

SQL> @interp
x This should print
x---------------------
x1 This should print
x1---------------------
y2 This should print
y2---------------------
Start of tests
==================
x is [1]
x is [2]
x is [3]
End of Tests

PFCLScript Execution Time (Seconds) : +000000 00:00:05.265551000
SQL>

This is a simple example of our language being interpreted and executed in PL/SQL. It is not blindingly fast as it took but that is fine; we have ways in the future we can speed this up by reducing the size of the script and also potentially reducing the size of the PL/SQL. We can work on performance of the interpreter after we are happy with its functionality.

Here is a second simple example in the script language that implements a nested loop in our language to print out a grid of numbers:

declare
lv_prog varchar2(32767):=q'[
LET m=2
LET x=1
PRINT "Start of tests"
PRINT "=================="
LOOP
LET y=1
LOOP
PRINT "x, y is [";x;",";y;"]"
IF y>m THEN
EXIT
FI
LET y=y+1
POOL
IF x>m THEN
EXIT
FI
LET x=x+1
POOL
PRINT "=================="
PRINT "End of Tests"
END
]';
begin
--
pfclscript.init(true,1);
pfclscript.run(lv_prog);
--
end;
/

Running this example shows:

SQL> @interp
Start of tests
==================
x, y is [1,1]
x, y is [1,2]
x, y is [1,3]
x, y is [2,1]
x, y is [2,2]
x, y is [2,3]
x, y is [3,1]
x, y is [3,2]
x, y is [3,3]
==================
End of Tests

PFCLScript Execution Time (Seconds) : +000000 00:00:11.041386000
SQL>

Whilst this is a shorter example than the first its slower at 11 seconds execution time as its more complex but it shows some great features of the language with a loop nested in another loop and two uses of IF/EXIT/FI to escape the loops. The PRINT statement with its dynamic parameter list is powerful where we can mix variables values and strings. This is similar in function but not syntax to the C language ... and things like printf()

The interpreter is around 850 lines of PL/SQL that implements some reasonable features of a programming language. I now call it PFCLScript rather than a simple version of BASIC; we can still write BASIC like code but now much better code.

I hope to get some speaking slots at conferences later this year and be able to demonstrate and show the design around this code.

#oracleace #sym_42 #oracle #plsql #secure #code #securecode #interpreter #vm #cpu #compiler #parser