Monday, December 12, 2005

Unlocking the Uniface repository. Part I.

Maintaining other people's code is ok if it is well designed, with clear and up to date documentation. But if the code is badly designed (if it ever was) with outdated or non-existent documentation, with the aggravating that it is made with an old out-of-the-market closed-source tool... well, it can be challenging.

That is my reality at work, maintaining an aberration, partially written in a tool from Compuware called Uniface, in its version 7.2.06, which is not supported any more.

Concerned about security, I started to audit this "software". And there I was, in front of around 1200 lines of code to replace to begin with. I can't, for obvious reasons, explain more about the flaw ;-) but I can tell you that these ~1200 lines scattered all over the source code had a pattern in common.

I can hear the Perl hackers saying: "just pass them through a regex". But Uniface 7.2.06 is cooked apart, as we use to say in Mexico, when speaking of source code storage.

A Uniface project's source code is not maintained as files in a filesystem. It is stored in a database in its own undocumented way, or not publicly available for that matter. I couldn't find any information about it on the web nor in the Uniface CDs. I bet I have to pay for some advanced training.

Uniface hackers would advise: "if you want to access the repository install the metadictionary". It's true that the metadictionary "decodes" the source code stored in the database, but I need to write a Uniface application that makes use of the new entities created by the metadictionary and still don't get my find & replace + regular expressions with it.

And you guessed it: Uniface 7.2.06 has no option to find & replace text outside a trigger (a piece of code assigned to a component, model, entity, etc...), let alone regular expressions. Heck, even this find & replace option is an undocumented feature. Go figure.

Exporting the source code to XML was no option, Uniface 7.2.06 doesn't eat its own dog food: it cannot load the XML file that itself generates. Exporting to and editing a TRX file is possible, but not supported by Compuware, and would require loading back the whole repository again.

I had no options left: to start modifying each of those ~1200 lines, one by one. Such is life.

Of course not.

Stay tuned for the second tech note about this topic and watch the Uniface repository in Eve's dress.


JM Chopin said...

There is a german guy who wrote a tool for you called Code Inspector: Ulrich Feiden at EDV Beratung Feiden GmbH, Exactly what you are looking for. I used it and it worked fine. May it is now a freeware?
Anyway, exporting in TRX and editing with an editor supporting the wrapping is also a good solution. After change, you just have to re-import the code and it should not be a problem.
An another solution is to work directly on the Uniface tables in your database. It is quite dangerous since triggers are packed in one database field but some friends of mine worked like that.
Jean-Michel Chopin,

Gerardo Santana said...

Hello JM

I tried to open and got a 404 error code.

The problem with the TRX export approach was searching for a pattern, in order to substitute the matches with a string, because the wrapping would make it at least less easy.

I solved it writing a Ruby script that can pack and unpack the information about forms and components stored in the Uniface tables.

How the info is encoded, the routines to unencoded it and the whole Ruby source code to search and replace inplace will be published in the following parts.

Ronny said...

Hello Garardo,
I just wanted to know how you ended up with this project.
Did you manage to unlock / re-write the repository for your needs?
Just curios.

jim caprioli said...

Did you ever publish part II of this interesting story? How did it end?

Gerardo Santana said...

Hi Ronny and Jim.

I'll work on part II soon. I got distracted by my day job ;) and Ruby/Informix.

The second part is about "decoding" the code stored by Uniface in the database and manipulating it freely and easily through some Ruby classes.

Thanks for your interest.