Browse Source

* changed a lot of "if fm.mode = fmClosed then" to case statements,
because if f is not yet initialized, the mode is invalid and can
contain another value even though the file is closed
+ check if a file is open in writeln_end (caused crash if used on
not opened files)

Jonas Maebe 25 years ago
parent
commit
17c623dc25
3 changed files with 203 additions and 173 deletions
  1. 42 59
      rtl/inc/file.inc
  2. 137 108
      rtl/inc/text.inc
  3. 24 6
      rtl/inc/typefile.inc

+ 42 - 59
rtl/inc/file.inc

@@ -133,14 +133,12 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmOutput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    fmInOut,fmOutput :
+      Result:=Do_Write(FileRec(f).Handle,Longint(@Buf),Count*FileRec(f).RecSize)
+        div FileRec(f).RecSize;
+    fmInPut: inOutRes := 105;
+    else InOutRes:=103;
   end;
-  Result:=Do_Write(FileRec(f).Handle,Longint(@Buf),Count*FileRec(f).RecSize) div FileRec(f).RecSize;
 End;
 
 
@@ -192,14 +190,12 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmInput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    fmInOut,fmInput : 
+      Result:=Do_Read(FileRec(f).Handle,Longint(@Buf),count*FileRec(f).RecSize)
+        div FileRec(f).RecSize;
+    fmOutput: inOutRes := 104;
+    else InOutRes:=103;
   end;
-  Result:=Do_Read(FileRec(f).Handle,Longint(@Buf),count*FileRec(f).RecSize) div FileRec(f).RecSize;
 End;
 
 
@@ -252,14 +248,11 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmInput,fmOutput : ;
-  else
-    begin
+    fmInOut,fmInput,fmOutput :
+      FilePos:=Do_FilePos(FileRec(f).Handle) div FileRec(f).RecSize;
+    else
       InOutRes:=103;
-      exit;
-    end;
   end;
-  FilePos:=Do_FilePos(FileRec(f).Handle) div FileRec(f).RecSize;
 End;
 
 
@@ -272,15 +265,13 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmInput,fmOutput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    fmInOut,fmInput,fmOutput :
+      begin
+        if (FileRec(f).RecSize>0) then
+          FileSize:=Do_FileSize(FileRec(f).Handle) div FileRec(f).RecSize;
+      end;
+    else InOutRes:=103;
   end;
-  if (FileRec(f).RecSize>0) then
-   FileSize:=Do_FileSize(FileRec(f).Handle) div FileRec(f).RecSize;
 End;
 
 
@@ -293,15 +284,10 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmInput,fmOutput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    {Can't use do_ routines because we need record support}
+    fmInOut,fmInput,fmOutput : Eof:=(FileSize(f)<=FilePos(f));
+    else InOutRes:=103;
   end;
-  {Can't use do_ routines because we need record support}
-  Eof:=(FileSize(f)<=FilePos(f));
 End;
 
 
@@ -313,14 +299,10 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmInput,fmOutput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    fmInOut,fmInput,fmOutput :
+      Do_Seek(FileRec(f).Handle,Pos*FileRec(f).RecSize);
+    else InOutRes:=103;
   end;
-  Do_Seek(FileRec(f).Handle,Pos*FileRec(f).RecSize);
 End;
 
 
@@ -332,14 +314,10 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmOutput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    fmInOut,fmOutput :
+      Do_Truncate(FileRec(f).Handle,FilePos(f)*FileRec(f).RecSize);
+    else InOutRes:=103;
   end;
-  Do_Truncate(FileRec(f).Handle,FilePos(f)*FileRec(f).RecSize);
 End;
 
 
@@ -351,15 +329,13 @@ Begin
   If InOutRes <> 0 then
    exit;
   case FileRec(f).Mode of
-    fmInOut,fmInput,fmOutput : ;
-  else
-    begin
-      InOutRes:=103;
-      exit;
-    end;
+    fmInOut,fmInput,fmOutput :
+      begin
+        Do_Close(FileRec(f).Handle);
+        FileRec(f).mode:=fmClosed;
+      end
+    else InOutRes:=103;
   end;
-  FileRec(f).mode:=fmClosed;
-  Do_Close(FileRec(f).Handle);
 End;
 
 
@@ -409,7 +385,14 @@ End;
 
 {
   $Log$
-  Revision 1.19  2000-02-09 16:59:29  peter
+  Revision 1.20  2000-03-24 10:26:18  jonas
+    * changed a lot of "if fm.mode = fmClosed then" to case statements,
+      because if f is not yet initialized, the mode is invalid and can
+      contain another value even though the file is closed
+    + check if a file is open in writeln_end (caused crash if used on
+      not opened files)
+
+  Revision 1.19  2000/02/09 16:59:29  peter
     * truncated log
 
   Revision 1.18  2000/01/17 20:02:30  peter

+ 137 - 108
rtl/inc/text.inc

@@ -32,7 +32,6 @@ Begin
   t.Handle:=UnusedHandle;
 End;
 
-
 Procedure FileReadFunc(var t:TextRec);
 Begin
   t.BufEnd:=Do_Read(t.Handle,Longint(t.Bufptr),t.BufSize);
@@ -46,7 +45,7 @@ var
 Begin
   i:=Do_Write(t.Handle,Longint(t.Bufptr),t.BufPos);
   if i<>t.BufPos then
-   InOutRes:=101;
+    InOutRes:=101;
   t.BufPos:=0;
 End;
 
@@ -112,21 +111,24 @@ Procedure Close(var t : Text);[IOCheck];
 Begin
   if InOutRes<>0 then
    Exit;
-  If (TextRec(t).mode<>fmClosed) Then
-   Begin
-   { Write pending buffer }
-     If Textrec(t).Mode=fmoutput then
-       FileFunc(TextRec(t).InOutFunc)(TextRec(t));
-     TextRec(t).mode:=fmClosed;
-   { Only close functions not connected to stdout.}
-     If ((TextRec(t).Handle<>StdInputHandle) and
-         (TextRec(t).Handle<>StdOutputHandle) and
-         (TextRec(t).Handle<>StdErrorHandle)) Then
-      FileFunc(TextRec(t).CloseFunc)(TextRec(t));
-   { Reset buffer for safety }
-     TextRec(t).BufPos:=0;
-     TextRec(t).BufEnd:=0;
-   End;
+  case TextRec(t).mode of
+    fmInput,fmOutPut,fmAppend:
+      Begin
+        { Write pending buffer }
+        If Textrec(t).Mode=fmoutput then
+          FileFunc(TextRec(t).InOutFunc)(TextRec(t));
+        { Only close functions not connected to stdout.}
+        If ((TextRec(t).Handle<>StdInputHandle) and
+            (TextRec(t).Handle<>StdOutputHandle) and
+            (TextRec(t).Handle<>StdErrorHandle)) Then
+          FileFunc(TextRec(t).CloseFunc)(TextRec(t));
+        TextRec(t).mode := fmClosed;
+        { Reset buffer for safety }
+        TextRec(t).BufPos:=0;
+        TextRec(t).BufEnd:=0;
+      End
+    else inOutRes := 103;
+  End;
 End;
 
 
@@ -181,10 +183,10 @@ Begin
    exit;
   if TextRec(t).mode<>fmOutput then
    begin
-     if TextRec(t).mode=fmClosed then
-      InOutRes:=103
+     if TextRec(t).mode=fmInput then
+      InOutRes:=105
      else
-      InOutRes:=105;
+      InOutRes:=103;
      exit;
    end;
 { Not the flushfunc but the inoutfunc should be used, becuase that
@@ -244,10 +246,10 @@ Begin
    exit(true);
   if (TextRec(t).mode<>fmInput) Then
    begin
-     if TextRec(t).mode=fmClosed then
-      InOutRes:=103
+     if TextRec(t).mode=fmOutput then
+      InOutRes:=104
      else
-      InOutRes:=104;
+      InOutRes:=103;
      exit(true);
    end;
   If TextRec(t).BufPos>=TextRec(t).BufEnd Then
@@ -276,10 +278,10 @@ Begin
    exit(true);
   if (TextRec(t).mode<>fmInput) Then
    begin
-     if TextRec(t).mode=fmClosed then
-      InOutRes:=103
+     if TextRec(t).mode=fmOutPut then
+      InOutRes:=104
      else
-      InOutRes:=104;
+      InOutRes:=103;
      exit(true);
    end;
   repeat
@@ -313,10 +315,10 @@ Begin
    exit(true);
   if (TextRec(t).mode<>fmInput) Then
    begin
-     if TextRec(t).mode=fmClosed then
-      InOutRes:=103
+     if TextRec(t).mode=fmOutPut then
+      InOutRes:=104
      else
-      InOutRes:=104;
+      InOutRes:=103;
      exit(true);
    end;
   If TextRec(t).BufPos>=TextRec(t).BufEnd Then
@@ -341,10 +343,10 @@ Begin
    exit(true);
   if (TextRec(t).mode<>fmInput) Then
    begin
-     if TextRec(t).mode=fmClosed then
-      InOutRes:=103
+     if TextRec(t).mode=fmOutput then
+      InOutRes:=104
      else
-      InOutRes:=104;
+      InOutRes:=103;
      exit(true);
    end;
   repeat
@@ -447,11 +449,18 @@ const
 {$ENDIF SHORT_LINEBREAK}
 begin
   If InOutRes <> 0 then exit;
-{ Write EOL }
-  WriteBuffer(f,eol,eollen);
-{ Flush }
-  if f.FlushFunc<>nil then
-   FileFunc(f.FlushFunc)(f);
+  case f.mode of
+    fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
+      begin
+        { Write EOL }
+        WriteBuffer(f,eol,eollen);
+        { Flush }
+        if f.FlushFunc<>nil then
+          FileFunc(f.FlushFunc)(f);
+      end;
+    fmInput: InOutRes:=105
+    else InOutRes:=103;
+  end;
 end;
 
 
@@ -459,17 +468,16 @@ Procedure Write_Str(Len : Longint;var f : TextRec;const s : String);[Public,Alia
 Begin
   If (InOutRes<>0) then
    exit;
-  if (f.mode<>fmOutput) Then
-   begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=105;
-     exit;
-   end;
-  If Len>Length(s) Then
-   WriteBlanks(f,Len-Length(s));
-  WriteBuffer(f,s[1],Length(s));
+  case f.mode of
+    fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
+      begin
+        If Len>Length(s) Then
+          WriteBlanks(f,Len-Length(s));
+        WriteBuffer(f,s[1],Length(s));
+      end;
+    fmInput: InOutRes:=105
+    else InOutRes:=103;
+  end;
 End;
 
 
@@ -480,21 +488,20 @@ var
 Begin
   If (InOutRes<>0) then
    exit;
-  if (f.mode<>fmOutput) Then
-   begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=105;
-     exit;
-   end;
-  p:=pchar(@s);
-  ArrayLen:=StrLen(p);
-  if ArrayLen>sizeof(s) then
-   ArrayLen:=sizeof(s);
-  If Len>ArrayLen Then
-   WriteBlanks(f,Len-ArrayLen);
-  WriteBuffer(f,p^,ArrayLen);
+  case f.mode of
+    fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
+      begin
+        p:=pchar(@s);
+        ArrayLen:=StrLen(p);
+        if ArrayLen>sizeof(s) then
+          ArrayLen:=sizeof(s);
+        If Len>ArrayLen Then
+          WriteBlanks(f,Len-ArrayLen);
+        WriteBuffer(f,p^,ArrayLen);
+      end;
+    fmInput: InOutRes:=105
+    else InOutRes:=103;
+  end;
 End;
 
 
@@ -504,18 +511,17 @@ var
 Begin
   If (p=nil) or (InOutRes<>0) then
    exit;
-  if (f.mode<>fmOutput) Then
-   begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=105;
-     exit;
-   end;
-  PCharLen:=StrLen(p);
-  If Len>PCharLen Then
-   WriteBlanks(f,Len-PCharLen);
-  WriteBuffer(f,p^,PCharLen);
+  case f.mode of
+    fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
+      begin
+        PCharLen:=StrLen(p);
+        If Len>PCharLen Then
+          WriteBlanks(f,Len-PCharLen);
+        WriteBuffer(f,p^,PCharLen);
+      end;
+    fmInput: InOutRes:=105
+    else InOutRes:=103;
+  end;
 End;
 
 
@@ -686,10 +692,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+      fmOutPut,fmAppend:
+        InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
   if f.BufPos>=f.BufEnd Then
@@ -744,10 +752,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
 { Read maximal until Maxlen is reached }
@@ -824,10 +834,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
 { Read next char or EOF }
@@ -853,10 +865,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
   If f.BufPos>=f.BufEnd Then
@@ -881,10 +895,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
   If f.BufPos>=f.BufEnd Then
@@ -909,10 +925,12 @@ begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
   If f.BufPos>=f.BufEnd Then
@@ -938,10 +956,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
   If f.BufPos>=f.BufEnd Then
@@ -965,10 +985,12 @@ Begin
    exit;
   if (f.mode<>fmInput) Then
    begin
-     if TextRec(f).mode=fmClosed then
-      InOutRes:=103
-     else
-      InOutRes:=104;
+     case TextRec(f).mode of
+       fmOutPut,fmAppend:
+         InOutRes:=104
+       else
+         InOutRes:=103;
+     end;
      exit;
    end;
   If f.BufPos>=f.BufEnd Then
@@ -1009,7 +1031,14 @@ end;
 
 {
   $Log$
-  Revision 1.71  2000-03-19 08:36:41  peter
+  Revision 1.72  2000-03-24 10:26:18  jonas
+    * changed a lot of "if fm.mode = fmClosed then" to case statements,
+      because if f is not yet initialized, the mode is invalid and can
+      contain another value even though the file is closed
+    + check if a file is open in writeln_end (caused crash if used on
+      not opened files)
+
+  Revision 1.71  2000/03/19 08:36:41  peter
     * length check for readnumeric
 
   Revision 1.70  2000/03/17 21:27:56  jonas

+ 24 - 6
rtl/inc/typefile.inc

@@ -66,24 +66,42 @@ Procedure Int_Typed_Write(TypeSize : Longint;var f : TypedFile;var Buf);[IOCheck
 Begin
   If InOutRes <> 0 then
    exit;
-  Do_Write(FileRec(f).Handle,Longint(@Buf),TypeSize);
+  case fileRec(f).mode of
+    fmOutPut,fmInOut:
+      Do_Write(FileRec(f).Handle,Longint(@Buf),TypeSize);
+    fmInput: inOutRes := 105;
+    else inOutRes := 103;
+  end;
 End;
 
-
 Procedure Int_Typed_Read(TypeSize : Longint;var f : TypedFile;var Buf);[IOCheck, Public, Alias :'FPC_TYPED_READ'];
 var
   Result : Longint;
 Begin
   If InOutRes <> 0 then
    exit;
-  Result:=Do_Read(FileRec(f).Handle,Longint(@Buf),TypeSize);
-  If Result<TypeSize Then
-   InOutRes:=100;
+  case FileRec(f).mode of
+    fmInput,fmInOut:
+      begin
+        Result:=Do_Read(FileRec(f).Handle,Longint(@Buf),TypeSize);
+        If Result<TypeSize Then
+         InOutRes:=100
+      end;
+    fmOutPut: inOutRes := 104
+    else inOutRes := 103;
+  end;
 End;
 
 {
   $Log$
-  Revision 1.9  2000-02-09 16:59:31  peter
+  Revision 1.10  2000-03-24 10:26:19  jonas
+    * changed a lot of "if fm.mode = fmClosed then" to case statements,
+      because if f is not yet initialized, the mode is invalid and can
+      contain another value even though the file is closed
+    + check if a file is open in writeln_end (caused crash if used on
+      not opened files)
+
+  Revision 1.9  2000/02/09 16:59:31  peter
     * truncated log
 
   Revision 1.8  2000/01/07 16:41:37  daniel