Tuesday, December 21, 2004

Private vs Protected

Pretty much every object oriented programming language let's you set the visibility of object members. Usually it defaults to public. That means everybody can access that member. Ofcourse often you don't want to other objects to access certain parts of your object. This is where private or protected come in to play.

Limiting members access

An object should only expose members that really need to be accessed from the outside. All other members should be "hidden". It's not just a security issue but also creates nicer foot prints to work with the code. For example IDEs only have to list the public accessable functions in their "code insight" (or whatever you want to call it) listing. The public members are the members to work with, it also makes it easier for you to find what entry points you need to use on an object (in case it's not your code).

Private

The actual outcome of this depends on the language. But usually it comes down that only the objects within the same scope can access this member, subclasses do no have access to this member. What the scope is depends on the language used, often the scope is just the object itself. In ObjectPascal however the scope is the unit file (the source code).

One of the basics of OOP is that you can extend an object and add additional functionality. And usually you can only add additional functionlity outside of the "scope" because you can either not touch the original source or you simply shouldn't.
Using private to protect members of an object will prevent an subclass to work with these members. This is often needed.

Protected

Protected is similar to private except that subclasses can always access these members no matter if they are in the same scope.

Making members protected opens a security issue for those members. Since a subclass has access to these members it's possible to work around security measures.

How to choose

I'm sure somebody already though about that, however I am not aware of a document that introduces a formal method for member accessability. If such document would exist it would be very technical for most programmers to understand, or at least it would way to time consuming. That doesn't mean it's not wise to read it and use it's methods.

Here's a simple classification scheme I think should work well enough for most people.

  1. Is the member valuable to access from other classes? (1)
    Yes -> go to 2; No -> go to 3.
  2. Is it a variable?
    Yes -> go to 2.1; No (it's a function) -> public
    1. Should this variable be read-only? (2)
      Yes -> create a public accessor function and go to 3; No -> public
  3. Does the member contain\give access to security sensitive information? (3)
    Yes -> go to 3.1; No -> protected
    1. Is it a variable?
      Yes -> go to 3.1.1; No -> go to 3.2
      1. Should a subclass be able to write this member?
        Yes -> go to 3.3; No -> go to 3.1.2
        1. Should a subclass be able to read this member?
          Yes -> private and create a protected accessor method; No -> private
      2. Does this member give readonly access?
        Yes -> go to 3.2.1; No -> go to 3.3
        1. May a subclass read this data? (4)
          Yes -> protected; No -> private
      3. Does the new value need to be validated? (5)
        Yes -> private and create a protected method that will validate and set the private method; No -> protected
Only in a few cases the member will become and isolated private member (e.g. unable to read\write to the member).

1.
This is quite a difficult question, is the member for internal use only? When is something for internal use only? Things like buffers and pointers are usually for internal use only. Maybe somebody else can shed some light on this question.
2.
Very often you want to be able to give other classes access to certain variables, like the current position of a parser, but you don't want them to be able to modify the value. For this you should create an accessor function getMyVariable() that will simply return the current value of the variable.
3.
When is something security sensitive? Things like keys and passwords and sensitive. But it's not limited to authentication related information, sometimes things like an URI could be sensitive. Things that might need to be validated before they are used are security sensitive. For example in games you might want to give a user the freedom so configure some client side things. However, these things could be abused for cheating. So the settings need to be validated before they are set.
4.
In only a very few cases you want to prevent a subclass from reading certain variables. It's pretty much only the case for keys and passwords. Even though a subclass might have set the value via an other method it still doesn't mean it should be able to read a password.
5.
In some cases you want to give a subclass the right to set a new value, but you also want to validate the new value to meet certain security measures. For this you need to make sure the subclass has to use your method to set the new value and not be able to override it with it's own faulty method. Most languages provide the means to do this (UnrealScript allows you to mark a function as final, thus preventing it to be overwritten by a subclass). There is a trick to do this. Simply make the member private so it can't be accessed from the subclass and create protected accessor methods (get and set). In your set method you will validate the new value and pass it to the protected member. This way subclasses will have to use the parent set method in order to write the new value.
 //pseudo code

 var private string SensitiveInfo;

 protected function bool SetSensitiveInfo(string newValue)
 {
  if (newValue doesn't meet constraints) return false;
  SensitiveInfo = newValue;
  return true;
 }

 protected function string GetSensitiveInfo()
 {
  return SensitiveInfo;
 }
 

Thursday, October 14, 2004

MSIE and the <button> tag

MSIE doesn't really support the <button> as defined in the HTML 4 specification. Sure it does render a button, and something happens when you push on it. But it doesn't work as specified.

Why use <button> instead of a <input type="submit" ... />?

Simple, <button> gives you more power. For example, with the <button> tag the text on the button is different that the value submitted when the button is clicked. this is very usefull when you want to use a nicer description and don't want to use ugly value checks in your backend script.
<input type="submit" name="mybutton" value="add this new entry" /> displays:

When submitted the following details will be received by the back end script: mybutton = "add this new entry"
Sure it works when you only have only one button. But what if you have two buttons:

Now you will have to check the value of the action variable. It would be much nicer in the code if that value would be addChild or addSibling (also better for localization). But this is not possible with the <input> element.
That's where the <button> tag is usefull:
<button name="action" value="addChild" />add as child<button></button name="action" value="addSibling" />add as sibling</button> produces:

Depending on which button is pressed the value of action would be either addChild or addSibling while the text on the button is descriptive.
Another thing about the <button> is, that it's easier to use for style sheets, you don't have to set a special CSS class for all buttons (since not all Browsers support Input[type="submit"] elements in CSS).

But MSIE is broken

The <button> in MSIE doesn't work as it should. Instead of sending the value of the value property, it will send the value of the innerText (note: this is documented on MSDN), in other words, it will just behave like a normal <input> .
Another thing is that MSIE will include all <button> elements in the submit data, not just the one of the pressed button. So you would get something like: ?action=addChild&action=addSibling. This makes the button element complete useless since you don't know what button was pressed. This incorrect behavior isn't even documented on the MSDN.

A ugly workaround

I came up with an ugly workaround for just MSIE. It uses some javascript. Instead of creating a submit button I will create a normal button: <button type="button" onclick="onButtonClick(this, 'action', 'addChild')">Add as a child
Note, no value and no name have been set, this is very important. When this button is clicked it will call the following JavaScript code:
function onButtonClick(btn, name, value)
{
 btn.name = name;
 btn.value = value;
 btn.form.submit();
}
This will simply set the name of the button pressed to the desired name and set the value. After which it will submit the form.
Now when the button is pressed the text on the button will change to the desired value (yep, that's also incorrect behavior). But the form is submitted at once so it doesn't hurt a lot.
This bug exists in all MSIE versions that support the <button> tag, up to MSIE 6 sp2.
If everybody would switch to browsers that did support the standards as defined (like Mozilla, Firefox, or Opera) it wouldn't be a problem.

Friday, October 08, 2004

UnrealWiki Dev Journal 27-09-2004

UnCodeX Tribes:V ponderings:

Interfaces

Currently, there's only one root for the class tree. I'm going to add a new root item "Interfaces" that contains all interfaces.

Interfaces don't have parents, so this would be the best choice.
Things to think about:
  • auto expand Object works differently with more than 1 root node
  • no create subclass menu item for interfaces

Defines

I may have to redesign my complete parsing system. Maybe have to move it to a single pass parser. Right now I first construct the class tree, after that I analyse all the classes. This might not be possible anymore because of the #if ... #endif macros.
I'm pretty sure it's not possible to have a different class name, however, it might be possible that the parent class can be changed using these macros. So I would have to construct the tree and analyse the packages at the same time so all #defines are catched. The best method might be to mimick the way the unrealscript compiler does it: per package. This ofcourse would re-introduce the package order mechanism. This would be the nicest solution.

The other solution would be to extend the package scanner to parse through the whole source file every time just to capture the #define, #if...#endif macros.
Another thing I need to know is if the #define macros are system wide, or only for the subclasses. Most #defines are afaik in the Object class, so that would automatically make them system wide.
Also I would need to implement a expression evaluator for the #if macro.

Imports

Depending on what the import directive does I might have to implement this too. Mostlikely it's just identical to the #import macro, which will simply import type declarations. In this case I don't need to change anything (except to ingore the import lines).

Friday, September 24, 2004

UnrealWiki Dev Journal 24-09-2004

LibHTTP 3 is getting pretty solid. I've added a test class to perform various requests. I already found a few minor bugs using that test class, bugs that have been in there for quite some time.
The build is currently 133KiB, I'm not going to strip source from the package because of the simple reason that you can no longer use the package during compile time, only run-time. Stripping the source would reduce the package to 54KiB.
I've been thinking about creating a better source stripper. It doesn't strip the complete source, only the function and state body. The result would be that the TextBuffer (that usually contains the source code) only contains the declarations. This should be enough to use the package for compiling, and have a minimal size. I would add a comment to the top of the TextBuffer explaining that the code was removed to reduce size and stuff. However, creating such a tool isn't every easy. You can't simply replace the TextBuffer with a new one, you will have to update all the offsets in the file. Note that this tool is not for code protection, because you can still decompile the package. It's just to reduce the size.

Sunday, September 19, 2004

UnrealWiki Dev Journal 19-09-2004

Well found some time to work on LibHTTP version 3. So far I've made the following changes:

  • Improved easy of use: get(), post(), head()
  • Support for multipart/form-data POST data
  • Two different transfer modes: Normal and Fast (tries to download as much data as allowed within a single tick)
Previously you had to use HttpRequest to perform a request. I made this function protected and added functions for each HTTP request method. The HttpRequest function wasn't really a nice way to perform requests. Now you will have to set the cookie data before doing a request. You can't include it with the request function (was kinda useless).
As for the POST request, now both x-url-encoded data and form-data request bodies are supported. I've added some easy to use functions to add form-data fields. Using multipart/form-data you will have much more control over the posted content, for example it's possible to use Base64 to send binary data.
I also added a additional transfer mode: Fast. This will try to download as much data as allowed (defined by a couple of variables) within a single tick. This is usefull when you need to make sure certain data is downloaded as fast as possible and system impact isn't a big issue.

That's pretty much all the ideas I had to put into the new LibHTTP version, if you have requests, let me know ASAP.
Also LibHTTP3 will be shipped with the source code stripped from the binary package. This is to reduce the file size (87 KiB vs 33KiB).
Ofcourse the source code will be included seperately with the package so you don't have to download it via CVS.

Saturday, September 11, 2004

downloads.UnrealAdmin.org

Ok, finished the new download section for the UnrealAdmin page. It's a rather gloryfied directory listing. With a couple of nice touches.
It will automatically include the README file, if it exists, in the directory listing. This is useful for directory descriptions.
Also if the file has an MD5 file (filename.md5) it will be added below the filename on the listing.
Additionally, when there's a text file attached to a other filename it will show a like [toggle info]. This link will open/close the text file inline with the entry in the directory listing. This feature can be used to display the readme file per file. Very usefull for patches.

To protect the download page from being abused by other site, deep linking directly to the files so it will look like they host the file, I've added checks on the referer. If a browser doesn't send a referer, or adds bogus data, a cookie will be used to check if the user saw the notice that UnrealAdmin.org hosted the site. Ofcourse this check will only be done on full featured clients like Mozilla, Opera and MSIE. Clients like lynx, links or wget will directly download the file. So when server admins can simply download the file directly to their server from a shell.
I don't really like this protection, but it's needed because there are quite some assholes out there.

Future additions to the download page will be at least:

  • search feature
  • stats? (or maybe just Webalizer Output)
Also we could use some mirrors (hosts that mimick hour directory structure and files so we could link to them directly). I haven't thought out yet how I'm going to add the links to the directory listing, but I'll figure that out by the time we have a mirror.
I was also think about giving Epic and Ryan Gordon an account on the machine to upload beta patches directly for an instant mirror. The last beta patch for linux failed completely because Ryan's "0day" server was overloaded.

Thursday, September 09, 2004

UnrealAdmin.org - the future

I am one of the main admins on the UnrealAdmin page (ua.org). Ever since the site was started by Azazel we've been growing, and for a couple fo years we've been the authority for server administration for the Unreal games (Unreal Tournament, UT2003, UT2004). One of the main principles of our site is to stay independed as much as possible and remain free. Ofcourse being independed and free introduces some issues for hosting of the website.
In the beginning the site was hosted on a commercial host. But within a short time this wasn't enough to cope with the activity. Multiplay UK (MPUK) jumped it and provided use with a nice shared hosting solution without any hooks attached. This was great, it allowed us to continue growing. Over time ideas came up to expand our services, for that to work we need a dedicated hosting solution.
A little while ago GameServers.net (gs.net) offered to host our site. Since we where happy with our current host gs.net had to make us a better offer. So they offered us a dedicated host, that was great, it would allow us to expand has we had planned (for the future). After some discussion within the admin team we decided to do it. But before we made the final dicision Azazel first wanted to talk with MPUK and thank them for their services. MPUK responded by offering a dedicated but "jail" host on a FreeBSD machine. Well, that was nice, now we could discuss if we would take th gs.net offer or the MPUK offer.
In case of gs.net we would have to put a banner of gs.net on every site, but we would get a dedicated machine with Linux ES (RedHat). In case of MPUK we would have the same deal as before, but get a dedicated machine with FreeBSD within a jail (so no full control). The jail wouldn't matter much, it's not like I would recompile a FreeBSD kernel. The main reason for tha jail would be to allow the MPUK admins to fix the machine after we "broke" it. I would be the main person to administer the software on the machine, and I didn't care if it was a FreeBSD jail or a RedHat hell. I would prefer a nice Debian Linux machine, but nobody offered that. So I left it up to Azazel and he decided to stay with MPUK. So when our MPUK related site admin (Killing) requested the jailed machine from the MPUK admins they wouldn't give it to us. Instead, they gave use a normal (no jail) FreeBSD machine, even better.
Well, last monday I got access to the machine to install apache, php and mysql for the initial setup to host our current site. To summerise: FreeBSD package system sucks big time compared to Debian. Also FreeBSD doesn't really use stable software via the package system. For example pkg_add -r mysql-server will install a MySQL 4.1 alpha server. I had to manually download the binary package for MySQL 4.0 (there was no 3.23 package available). The alternative was to compile it manually via the ports system. Also installing PHP and requested extentions isn't as easy in FreeBSD as it is in Debian. So after two days and quite some annoyance I finally installed Apache2, PHP5 and MySQL. Ofcourse our forum software vBulletin isn't compatible with PHP5. All my own PHP scripts work perfectly, but quite some things in vBulletin just didn't work. On their site they only stated that PHP5 support was still being tested, instead of just saying "it doesn't work out of the box". So I had to replace PHP5 with PHP4. After an hour or two messing with FreeBSD I had replaced it... It could have been easier.
Right now our new machine is being tested if the current site works as it should. With a little luck I'm going to issue a site move by the end of the week (sunday or something). For this work work smoothly I'm planning to create an additional hostname to point to the new location (www2.unrealadmin.org). This is to give people direct access to the site while the DNS entries have been updated for everybody (1 or 2 days).
After that we can start planning the new stuff in the future of UnrealAdmin.org.

UnrealWiki Dev Journal 09-09-2004

I've been rather busy with school the last two weeks. So I haven't done much.

Unreal Kart: nothing much has been done, I need to "re-activate" the team, they have been slacking. In the meanwhile I've been experimenting with bot AI and path finding (to understand it better). This experimentation will result in a new gametype: Deluder

Deluder: this new gametype is a tribute to the Developers of Incredible Power. It's a rather nice gametype from an old FPS game (you might now it). This gametype might be the first step on converting more of that old game. Right now I use it for experimentation for Unreal Kart to better understand bot AI and path finding. The most important part of this gametype is a roaving token that runs away from the players, so it has a somewhat reversed hunting AI. It's rather interesting, usually you want pawns to go somewhere, but in this case I want to pawn not to go somewhere. Right now the pawn tries to move away as much as possible. However, quite often it runs past the current players, and I don't want that to happen. So, in one of the test levels (Albatros) it get's stuck on AIMarker8, the AI script of that marker doesn't do anything usefull, and the pawn doesn't just jump off the ledge for some reason, so I have to figure out what it should do there.

UnCodeX: haven't done anything since the HTML Hints for the the application. Soon I hope to implement PascalScript in the documentation generation. But my motivation for this project isn't that high, for some reason it's not really recognised, maybe I just expect too much of it. UnDox received a shit load of attention, but UnCodeX is pretty much not present, or maybe I just don't see it. However, I did receive an email from Bruce Shankle a long time ago, he was quite impressed with it. I really wonder how many people use UnCodeX.

LibHTTP: I'm working on a new version of LibHTTP, version 3. This version won't be completely backwards compatible, even tho it has the same base code. This version will ofcourse contain a couple of bug fixes (actually, just one at the moment, and it was only a bug for the UT2003 build). Some of the new features will include: easier usage via get(), post() or head() functions. Also a faster download mode when download speed is ciritcal, this will try to download more data each tick (ofcourse with setable thresholds). I'm also going to implement a document cache, and maybe some some binary options. Anyway, if you have any feature requests, let me know.

Friday, August 27, 2004

Welcome to my blog

I'm not really into blogging, but I might give this a try.
It's better than updating a .plan, and people can add comments.

I'm planning to cross post my entries on my Unreal Wiki Dev Journal on this blog. But also other things that I can't post on that Dev Journal.