Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-01

constructor "guarantee" and other behavioural stuff

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Pierce Ng

Hi all,

I last used Pascal in school a long long time ago. Just discovered Free Pascal.

I have the following:

  type
    TNonceBytes = array[1..8] of byte;
    TNonce = class
      private
        pn: TNonceBytes;
        filled: boolean;
      public
        constructor create; overload;
      end;
  constructor TNonce.create;
  begin
    inherited;
    randombytes(pn, 8);
    filled := true;
  end;

Is "filled" necessary, or does the compiler guarantee that my overloaded constructor is called to fill "pn" with "real crypto" random bytes? I'd imagine that, if randombytes() isn't called, the content of pn might be whatever that happens to be in the memory that was allocated. By eyeballing, I won't be able to tell, but cryptographically it'll be catastrophic if pn contains random-looking but possibly predictable data.

On a related note, if I keep "filled" as an instance variable but leave the line "filled := true" out from the constructor, what is filled's value after the constructor is done?

Finally, remembering my programming languages course from my CS undergrad days, in the following, are TNonce and TNonceBytes allocated on the stack or from the heap, and should I care, given that, in this case, I am writing a security-sensitive program?

  procedure encrypt(ptext: TByteArray, var ctext: TByteArray);
  var
    n: TNonce;
  begin
    n := TNonce.create;
    ... whatever ...
  end;

Thanks. Cheers.

Pierce

Michael Van Canneyt
to Pierce Ng
Pierce Ng wrote 26 lines
Hi all, I last used Pascal in school a long long time ago. Just discovered Free Pascal. I have the following: type TNonceBytes = array[1..8] of byte; TNonce = class private pn: TNonceBytes; filled: boolean; public constructor create; overload; end; constructor TNonce.create; begin inherited; randombytes(pn, 8); filled := true; end; Is "filled" necessary, or does the compiler guarantee that my overloaded constructor is called to fill "pn" with "real crypto" random bytes?

Yes.

Show quoted text 5 lines
I'd imagine that, if randombytes() isn't called, the content of pn might be whatever that happens to be in the memory that was allocated. By eyeballing, I won't be able to tell, but cryptographically it'll be catastrophic if pn contains random-looking but possibly predictable data.

It will be instantiated with 0 when the constructor is called.

On a related note, if I keep "filled" as an instance variable but leave the line "filled := true" out from the constructor, what is filled's value after the constructor is done?

False.

The whole memory area used by an instance of a class is zeroed out.

Show quoted text 14 lines
Finally, remembering my programming languages course from my CS undergrad days, in the following, are TNonce and TNonceBytes allocated on the stack or from the heap, and should I care, given that, in this case, I am writing a security-sensitive program? procedure encrypt(ptext: TByteArray, var ctext: TByteArray); var n: TNonce; begin n := TNonce.create; ... whatever ... end;

a TNonce instance is allocated on the heap. All classes are allocated on the heap. TNonceBytes as a fixed-length array is part of the memory allocated for TNonce.

There are also the older style "objects", they are allocated on the stack.

Michael.

Sven Barth
to Pierce Ng: I last used Pascal in school a long long time ago. Just discovered Free Pascal. I have…
"Pierce Ng" wrote
Hi all, I last used Pascal in school a long long time ago. Just discovered Free

Pascal.

Show quoted text 23 lines
I have the following: type TNonceBytes = array[1..8] of byte; TNonce = class private pn: TNonceBytes; filled: boolean; public constructor create; overload; end; constructor TNonce.create; begin inherited; randombytes(pn, 8); filled := true; end; Is "filled" necessary, or does the compiler guarantee that my overloaded constructor is called to fill "pn" with "real crypto" random bytes?

Note: "overload" is only necessary if you have multiple methods of the same name with different parameters. What you probably meant is "override", but even that is only necessary if a method in the parent was declared as "virtual". For constructors this isn't normally necessary, except if you want to use class variables to instantiate the class. E.g.

=== code begin ===

type
  TNonceClass = class of TNonce;
var
  c: TNonceClass;
  o: TNonce;
begin
  c := TSomeSubNonce;
  o := c.Create;
end.

=== code end ===

In this example if the constructor in TNonce isn't declared as virtual (and the on in TSomeSubNonce not as override) the TNonce.Create will be called, otherwise TSomeSubNonce will be called.

I'd imagine that, if randombytes() isn't called, the content of pn might be whatever

that

happens to be in the memory that was allocated. By eyeballing, I won't be

able

to tell, but cryptographically it'll be catastrophic if pn contains random-looking but possibly predictable data. On a related note, if I keep "filled" as an instance variable but leave

the

line "filled := true" out from the constructor, what is filled's value after the constructor is done?

The memory area of a class instance is by default always initialized with 0s. So in this case "pn" will contain zeroes and "filled" will be "false". Sidenote: Strings will be '', objects, interfaces and dynamic arrays will be Nil.

Finally, remembering my programming languages course from my CS undergrad

days,

in the following, are TNonce and TNonceBytes allocated on the stack or

from the

Show quoted text 10 lines
heap, and should I care, given that, in this case, I am writing a security-sensitive program? procedure encrypt(ptext: TByteArray, var ctext: TByteArray); var n: TNonce; begin n := TNonce.create; ... whatever ... end;

Classes are *always* allocated on the heap. If you want to control whether something is allocated on the stack or the heap you need to use records or the Turbo Pascal-style objects.

I can't answer your question regarding the security-sensitivity though.

Regards,
Sven

Pierce Ng
to Sven Barth: Pascal. Note: "overload" is only necessary if you have multiple methods of the same name…
Sven Barth wrote 24 lines
Note: "overload" is only necessary if you have multiple methods of the same name with different parameters. What you probably meant is "override", but even that is only necessary if a method in the parent was declared as "virtual". For constructors this isn't normally necessary, except if you want to use class variables to instantiate the class. E.g. === code begin === type TNonceClass = class of TNonce; var c: TNonceClass; o: TNonce; begin c := TSomeSubNonce; o := c.Create; end. === code end === In this example if the constructor in TNonce isn't declared as virtual (and the on in TSomeSubNonce not as override) the TNonce.Create will be called, otherwise TSomeSubNonce will be called.

Thanks Sven. Haven't had a need to do stuff like this with Object Pascal for now, but for past several years I have been programming in Smalltalk so this looks familiar. :-)

Show quoted text 8 lines
The memory area of a class instance is by default always initialized with 0s. So in this case "pn" will contain zeroes and "filled" will be "false". Sidenote: Strings will be '', objects, interfaces and dynamic arrays will be Nil. Classes are *always* allocated on the heap. If you want to control whether something is allocated on the stack or the heap you need to use records or the Turbo Pascal-style objects.

Got it.

Cheers.

Pierce

Mark Morgan Lloyd
to Pierce Ng
Pierce Ng wrote 7 lines
> In this example if the constructor in TNonce isn't declared as virtual (and > the on in TSomeSubNonce not as override) the TNonce.Create will be called, > otherwise TSomeSubNonce will be called. Thanks Sven. Haven't had a need to do stuff like this with Object Pascal for now, but for past several years I have been programming in Smalltalk so this looks familiar. :-)

[GRIN]

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]