Object Oriented programs, Perl and others

From: Matthew Braid (mb_at_uq.net.au.invalid)
Date: 08/27/04


Date: Fri, 27 Aug 2004 15:06:00 +1000

Hi all,

I've been spending a lot of time lately writing a lot of objects for a project
here (so far about 60 objects and counting), and while I've been considering
security the whole way I've started thinking one level down on how to secure
objects from direct alteration if they were used as a library in some other
code. (At the moment this isn't _really_ an issue as the packages are not
available to users unless they go through controlled programs that don't allow
unknown code to run).

After tinkering, I've come up with the following pseudo-rules (please correct me
if I'm wrong here, and preferably give me pointers :)

1. If an object inherits from another object (in perl), it is free to
change/override any sub inside the parent.

2. There is no way to stop code from altering a class directly (eg, by doing
something like 'sub Object::_internal { something_unexpected() }'

3. The fixes I've so far run across (my'd hashes keyed on blessed references to
store instance data instead of using hashes for the base instance structure,
my'd subroutines for truly private methods) work (well, as far as they can
considering 1 and 2) but make inheritance an absolute nightmare - children can't
get hold of parent's protected data. Writing accessor methods for them is
problematic because of 2 - the accessor can be replaced to return something else.

4. Even if perl strictly adhered to OO paradigms I've learnt, some of these
problems are very hard to fix.

I've been thinking of theoretical ways to fix problems like this, and my
amateurish ideas so far have been:

1. Closing packages - from then on, no other code can enter that package's
namespace to specify subs, ie this:

   package Example is closed; # Made up syntax - maybe should be fatal if the
                              # Example namespace already exists
   our($Bar) = '123';
   sub foo { ... }

   package main;
   sub Example::foo { ... } # Fatal - modify closed package
   sub Example::other { ... } # Fatal - add to closed package
   $Example::Bar = '321'; # OK - not changing a sub

   package OtherExample;
   use base qw/Example/;

   sub foo { ... } # OK - this is an override, doesn't
                              # alter the Example package

This could be expanded to making packages 'append only' (only new subs added) as
well etc etc.

2. Closing subs - from then on, child packages and external code cannot override
a particular sub:

   package Example;

   sub foo is closed { ... } # More made up syntax. Maybe a warning if
                             # Example::foo is already defined
   sub bar { ... }

   package OtherExample;
   use base qw/Example/;
   sub foo { ... } # Fatal - the sub is closed and cannot be
                              # overriden, even by children
   sub bar { ... } # OK

   package main;
   sub Example::foo { ... } # Fatal - same reason as above

3. 'Closed Object Families' or 'Willed Inheritance'. This one breaks the idea
that a parent need not know anything about its children a bit, but it limits who
can inherit from it:

   package Example wills qw(OtherExample # Made up syntax - 'wills'
                            MoreExamples); # as in 'I hereby will my
                                           # stuff to the following
                                           # children...'
   ....

   package MoreExamples;
   use base qw/Example/; # OK - this is one of our 'trusted' children
   ....

   package UnexpectedExample;
   use base qw/Example/; # Fatal - not one of our trusted children, not allowed
                         # to inherit.

Using mixes of these, you can start to be confident to write accessors for
objects for finding out if they can do something potentially dangerous, or for
accessors to find out parameters for potentially dangerous actions, eg:

   package Example is closed, wills qw(OtherExample);
   my %Private;
   sub new {
     my $class = shift;
     my $self = bless('', $class); # short version :)
     $Private{$self} = {CanDelete => 0,
                        ID => 'someid'};
     return $self;
   }
   sub can_delete is closed {
     my $self = shift;
     return 0 if not exists $Private{$self}; # Safe default
     return $Private{$self}{CanDelete};
   }
   sub do_delete {
     my $self = shift;
     return 0 if not $self->can_delete;
     # Do the delete...
     return 1;
   }

Now instances of Example and OtherExample can safely assume that:

   $eg->can_delete

hasn't been overridden like:

   sub Example::can_delete { return 1 }

(and do_delete hasn't been modified by 'untrusted' code), so can be used in
arbitrary code as library code (...I think :) )

This is all just musings off the top of my head - for all I know perl has some
of this already that I don't know about, and I haven't descended to the level
below (how can I be sure the user loaded the right module and not something from
a private directory etc), _and_ nothing here defines what happens if a package
tries to inherit from a package that has inherited from a _willed_ package (sheesh!)

All up I think I've been thinking too much about this stuff anyway :)

MB



Relevant Pages

  • Re: Handle Worked - can someone please double check
    ... Ive been searching google with "inheritance" but things come up that I'm not ... the custom class (user control) will appear in your ... to get the _TrimText property somehow. ... Protected Overrides Sub OnLeave ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Abstract Form Class
    ... Visual inheritance is one of the key benefits of VB.NET. ... > This happens before I have put any other code on the system, all I have done is entered the MustInherits keyword - this is all the code in the form:> ... > Public Sub New ... > Protected Overloads Overrides Sub Dispose ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Re: Handle Worked - can someone please double check
    ... Public Class myTextBox ... Protected Overrides Sub OnLeave ... Private _TrimText As Boolean ... Inheritance is your friend in this case. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Sharing instances of objects between packages
    ... > packages when the child packages have their own object ... Is there a way to inherit the parent object? ... The House "is a" Building. ... Inheritance is basically about inheriting those metohds. ...
    (perl.beginners)
  • Re: method reference - repost
    ... you lose inheritance with Class::meth ... where only a literal method or single scalar var can be in the method ... BM> (If I am wrong then yes, clearly that is a sub rather than a method ... won't let it be called a real method call. ...
    (comp.lang.perl.misc)