Classic ASP - Detect line number and file from which a function is called? - asp-classic

Our application is made in good (?) ol' classic ASP. Not ideal but it works and it's pretty stable - has been for 10-15 years. It is not particularly well documented in places, such as where a 'translation' (client-controlled piece of text) appears. All we have against a translation is a clientid and translationid, neither of which are particularly helpful. I've tried searching the (10s of thousands of lines of) core code for gettrans(1) (translation 1) and can see that doing this for another 3100 is going to be a nightmare, not to mention inaccurate as there are many functions which are called with a transid passed into them, and then they call gettrans(transid).
My last thought on this matter is the possibility that we could maybe detect, from gettrans, where a function is called from - not just the line number but the file name of the include (thankfully the includes are named usefully so figuring out where a translation is used should not be too hard!). I highly doubt that it would be possible to get the include name on the basis that includes are processed before ASP, but I'll settle for the overall filename and then we can combine the includes to get to the line of code and log the include file name.
I very much doubt this is possible and can't find anything on SO or Google. Does anyone know of any way to achieve this, or have any pointers on what I might try? Thanks in advance.
Regards,
Richard

Most you can achieve is getting the currently executing script, which can be obtained by:
Dim currentPage
currentPage = Request.ServerVariables("SCRIPT_NAME")
When inside included page it will give you the "parent" page.
However getting "callee" information is not possible with classic ASP as far as I know, so you will have to add another parameter to the function being called then change all calls to pass the parameter in order to identify where it comes from. Looks like someone did something similar and called it ASP Profiler, use it at your own risk of course. (Never tried myself)

Related

Drupal WebForms Data Structure Reference?

I am relatively new to Drupal. We have a site and I've been asked to jump in and make some changes. I'm working on customizing the output of the Webforms module. I'm having trouble doing so because I can't seem to find a reference to the various data structures Webforms uses.
For example, I need to change something in a preprocess hook. Passed into the hook is a structure called $variables. I can see that attributes are being added to the piece I want to change, so I know I'm in the right hook. What I want to do is add something to the text. But I can't figure out where in $variables the text is so I can change it.
I'm sure what I need to change is in there, but I can't seem to get at it. All the documentation I've found on the web is either "paste this code in" or assumes you know the data structures.
So:
1. Is there a reference anywhere to these structures? $variables is one. $submission, $components are others. There are probably more. I know their contents vary widely with the specific webform, but looking for a general reference.
2. How can I see the contents of one of the structures from inside a hook? I've tried a lot of things, but no luck. Would be great to either have it output to the Apache log, or show up on the screen, something...
Any help would be greatly appreciated. It feels like there's real power here, but I can't get at it because I'm missing some basics.
I would say you need to install 2 modules to figure out what is going on...
First Devel, allowing you to use the dmp function. This will output a whole array to the message area.
And then my new favorite module, Search Krumo.
A webform is generated from large array of data and finding the bit that is relevant to you can often be difficult just looking though the dmp output. Search Krumo puts a search box in the message area allowing you to search for any instances of a string in the whole array structure. When you've found the bit that is relevant it also lets you copy the path to that array element so you can easily modify values buried deep in multi-arrays.
EDIT:
If you don't want the output on the screen but would rather log it then use Devel Debug Log. Very useful for debugging ajax requests etc.
If you just need to log simple strings not whole arrays then the dd function is useful combined with: tail -f /tmp/drupal_debug.txt assuming you have SSH access.

Drupal - change name of uploaded images to random alphanumeric long string

I've noticed that it is a common functionality within public sites to change the name of uploaded pictures to a long, 'random', alphanumeric string. This is good for privacy etc.
I can't find a module within Drupal that achieves this, and was wondering if it was possible. This would need to operate before modules like ImageCache.
???
I think there're no modules that does exactly what you're looking for, but i can suggest a way to achieve this using code. There's a module called filefield_paths which makes you able to change the name of imagefield files with a token, provided by the token module.
Looking into the code of this module you can see how it works and make your own small module to achieve the same result with an alphanumeric string.
In detail, the function you're looking for is here, at line 457.
I can't provide a directly working solution as I need time to write and test the code, however this is a very good starting point.

Token replacement

I currently implement a replace function in the page render method which replaces commonly used strings - such as replace [cfe] with the root to the customer front end. This is because the value may be different based on the version of the site - for example the root to the image folder ([imagepath]) is /Images on development and live, but /Test/Images on test.
I have a catalogue of products for which I would like to change [productName] to a link to the catalogue page for that product. I would like to go through the entire page and replace all instances of [someValue] with the relevant link. Currently I do this by looping through all the products in the product database and replacing [productName] with the link to the catalog page for that product. However this is limited to products which exist in the database. "Links" to products which have been removed currently wont be replaced, so [someValue] will be displayed to the user. This does not look good.
So you should be able to see my problem from this. Does anyone know of a way to achieve what I would like to easily? I could use regexes, but I don't have much experience of those. If this is the easiest way, using "For Each Match As String In Regex.Matches(blah, blah)" then I am willing to look further into this.
However at some point I would like to take this further - for example setting page layouts such as 3 columns with an image top right using [layout type="3colImageTopRight" imageURL="imageURL"]Content here[/layout]. I think I could kind of do this now, but I cant figure out how to deal with this if the imageURL were, say, [Image:Product01.gif] (using regex.match("[[a-zA-Z]{0,}]") I think would match just [layout type="3colImageTopRight" imageURL="[Image:Product01.gif] (it would not get to the end of the layout tag). Obviously the above wouldn't quite work, as I haven't included double quotes in the match string or anything, but you get the general idea. You should be able to get the general idea of what I am getting at and what I am trying to do though.
Does anyone have any ideas or pointers which could help me with this? Also if this is not strictly token replacement then please point me to what it is, so I can further develop this.
Aristos - hope reexplaining this resolves the confusion.
Thanks in advance,
Regards,
Richard Clarke
#RichardClarke - I would go with Regular Expressions, they're not as terrible to learn as you might think and with a bit of careful usage will solve your problems.
I've always found this a very useful tool.
http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx
goes nicely with a cheat sheet ;-)
http://www.addedbytes.com/cheat-sheets/regular-expressions-cheat-sheet/
Good luck.

Looking for a hack to prevent rewriting an app without using session variables

Our company uses an app that was originally ColdFusion + Access later converted to classic ASP + MS Sql for task/time tracking called the request system. It's broken down by department, so there's one for MIS, marketing, logistics, etc. The problem comes in when (mainly managers) are using more than one at a time, with 2 browser windows open. The request system uses session variables, a lot of session variables, "session" is referenced 2300 times in the application. When 2 are open at once as you can imagine this causes all sorts of anomalies from the variables getting mixed up.
There's a 3 year old MIS request in the system to "fix" this and it's been worked on by 3 developers, and now it's my turn to take a shot at it. I was wondering if anyone else has had to work on a project like this, and if there was some sort of hack to try and mitigate some of the problems. I was thinking of maybe calling something in global.asa to load misc. session variables from the querystring. The problem is, there's all sorts of this going on:
If (Session("Application") <> Request("App")) and Request("App") <> "" THEN
Session("Application") = Request("App")
End If
Looking at the functions in include files, you'll have a function with 4 parameters, that makes references to 6 different session variables. So you get the idea, this is going to be painful.
Has anyone had to do anything like this in the past? Any hacks you found useful?
refactor the code away from the direct Session("whatever") interface:
create an API for session access and replace all existing use of Session with it (it can be a session 'class/object' or just an include-file)
mangle the passed-in names for session variables with something that will make them unique per domain according to your needs (department or whatever)
test carefully
then rewrite the whole thing later in a modern web language, and/or find another job before they ask you to perform another miracle ;-)
My manager (who's a business guy, not a code guy), is infatuated with this system. He's in no rush to rewrite it. If I did rewrite this the only session variables used would be login-related. I'm more concerned with fast than right unfortunately :(
How many times "Session" is referenced doesn't mean as much as you seem to think it does. Also, unless there's a coding error, having two browsers open should start two separate sessions, and there shouldn't be any "mixing up" of the values for those sessions.
I suspect it may have to do with something else like both sessions reading from the same cookie or some issues with the App variables. Without seeing the whole source, its hard to say. It may be worth finding out if there's someone more familiar with the code to help you out.
And yes, its going to be painful to dig around in the code, but at least you'll know more the next time you have to fix something. ;)
Besides, rewriting isn't always the best option. You never know what sorts of fun business logic/bug fixes get lost in the rewrites.
I agree with AnonJr
Blockquote
having two browsers open should start two separate sessions
Blockquote
maybe the use of static global variables is causing your dataloss
In your sessions class (if you will use one), when you reference each variable, use a prefix or something common so that you can identify all your variables...then you can loop through ALL session variables and perhaps find others that are being referenced/created...
Private Const PREFIX As String = "MyPrefix_"
Public Shared Property MyVariable() As String
Get
Return HttpContext.Current.Session(String.Concat(PREFIX, "MyVariable"))
End Get
Set(ByVal value As String)
HttpContext.Current.Session(String.Concat(PREFIX, "MyVariable")) = value
End Set
End Property
loop to find session variables that aren't in your class
For Each Item As Object In HttpContext.Current.Session.Contents
If Not Item.ToString.StartsWith(PREFIX) Then
End If
Next

Replace huge Case statement in Classic ASP

I have a 200+ case statement in Classic ASP which is getting out of control. It sets 5 variables, based on which case is selected. Address, Phone, Name etc. Just sets the variables and nothing else in each case.
Databases or files are not an option for this application.
Coming from the Perl world I would use a hash to store this info.
Brian, the classic ASP equivalent of a Perl hash is the Scripting.Dictionary object.
Getting out of control? I think it's already out of control!
Can you not categorise the cases into 'x' general areas and split down into helper routines?
Depends on what you want for performance.
The case statement is ugly but does not consume memory that would need to be allocated.
However, you could create a class for your fields and load instances of them into a Dictionary. Perform this operation in the global.asp script so it only happens once. Store the dictionary in the global asp collection such that it is only allocated once but used with each page call.
My appologies for not getting too specific here... it's been a while.
A lot of people use VBScript for Classic ASP, but you can use JavaScript / JScript on the server as an alternative. As a matter of fact, this is my preferred way of doing Classic ASP before finally moving to .NET (except in some cases, you will have to mix in VBScript for special cases, i.e. Disconnected Recordset, ExecuteNoRecords, etc.). It will provide you with better OOP support vs VBScript. Maybe you can try refactor that to.some sort of Strategy pattern afterward. Worth looking into I guess for better maintenance in the long run.
The fact that you can't migrate this over to a database or a text file is a bit of an issue as they would be the best solution for this type of data. However, if you have to have it in the code you could always try putting it into a matrix that you predefine. Then you could provide a function that returns the data from a given row in the matrix.
Scripting dictionary is the best option IMHO.
This should be done with a database, but since you said that is not an option, nothing you will write will be any less complex than a switch statement, since it's all required to live in your code (according to your terms of no db and no files).
I mean, you could use an Excel Spreadsheet if the idea of a database is too complicated but technically that would be a file as well!

Resources