Changeset 438


Ignore:
Timestamp:
May 18, 2022, 11:12:29 AM (2 years ago)
Author:
chronos
Message:
  • Fixed: Data size was not correctly stored in server commands. Introduced in rev 435.
  • Fixed: Check data size for its maximum. Limit maximum length of unit and city name so it can fit into data block.
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/CmdList.pas

    r355 r438  
    55
    66uses
    7   Classes;
     7  Classes, SysUtils, Math;
    88
    99const
    1010  MaxDataSize = 1024;
     11  CommandDataElementSize = 4;
     12  CommandDataElementCountMask = $f;
     13  CommandDataMaxSize = CommandDataElementSize * CommandDataElementCountMask;
    1114
    1215type
     
    4447  end;
    4548
     49  function CommandWithData(Command: Integer; DataSize: Byte): Integer;
     50
     51resourcestring
     52  SCommandDataSizeError = 'Command data size %d out of range (0-%d).';
     53
     54
    4655implementation
    4756
     
    5564  TData = array [0 .. MaxDataSize - 1] of Cardinal;
    5665  PData = ^TData;
     66
     67function CommandWithData(Command: Integer; DataSize: Byte): Integer;
     68var
     69  DataElementCount: Byte;
     70begin
     71  if DataSize > CommandDataMaxSize then
     72    raise Exception.Create(Format(SCommandDataSizeError, [DataSize, CommandDataMaxSize]));
     73  DataElementCount := Ceil(DataSize / CommandDataElementSize);
     74  Result := Command or (DataElementCount and CommandDataElementCountMask);
     75end;
    5776
    5877constructor TCmdList.Create;
     
    139158    end;
    140159
    141     if Command and $F = 0 then
     160    if Command and CommandDataElementCountMask = 0 then
    142161      Data := nil
    143162    else
    144163    begin
    145164      Data := @LogData[FState.LoadPos];
    146       inc(FState.LoadPos, Command and $F * 4);
     165      inc(FState.LoadPos, Command and CommandDataElementCountMask * CommandDataElementSize);
    147166    end;
    148167  end;
     
    232251    end;
    233252  end;
    234   if Command and $F <> 0 then
    235     PutData(Data, Command and $F * 4);
     253  if Command and CommandDataElementCountMask <> 0 then
     254    PutData(Data, Command and CommandDataElementCountMask * CommandDataElementSize);
    236255end;
    237256
  • trunk/LocalPlayer/MessgEx.pas

    r429 r438  
    6464uses
    6565  ClientTools, BaseWin, Term, Help, UnitStat, Tribes, UPixelPointer,
    66   IsoEngine, Diagram, Sound;
     66  Diagram, Sound;
    6767
    6868{$R *.lfm}
  • trunk/LocalPlayer/Select.pas

    r435 r438  
    55
    66uses
    7   Protocol, ClientTools, Term, ScreenTools, IsoEngine, PVSB, BaseWin,
     7  Protocol, ClientTools, Term, ScreenTools, PVSB, BaseWin,
    88  LCLIntf, LCLType, Messages, SysUtils, Classes, Graphics, Controls, Forms,
    99  ExtCtrls, ButtonB, ButtonBase, Menus, Types;
     
    9999
    100100uses
    101   CityScreen, Help, UnitStat, Tribes, Inp;
     101  CityScreen, Help, UnitStat, Tribes, Inp, CmdList;
    102102
    103103{$R *.lfm}
     
    865865    CityNameInfo.ID := MyCity[cix].ID;
    866866    CityNameInfo.NewName := InputDlg.EInput.Text;
    867     Server(cSetCityName, me, 0, CityNameInfo);
     867    if CityNameInfo.GetCommandDataSize > CommandDataMaxSize then
     868      Delete(CityNameInfo.NewName, Length(CityNameInfo.NewName) -
     869        (CityNameInfo.GetCommandDataSize - 1 - CommandDataMaxSize), MaxInt);
     870    Server(CommandWithData(cSetCityName, CityNameInfo.GetCommandDataSize),
     871      me, 0, CityNameInfo);
    868872    if CityDlg.Visible then
    869873    begin
     
    871875      CityDlg.Invalidate;
    872876    end;
    873     result := true;
     877    Result := True;
    874878  end
    875879  else
    876     result := false;
     880    Result := False;
    877881end;
    878882
     
    890894    ModelNameInfo.mix := mix;
    891895    ModelNameInfo.NewName := InputDlg.EInput.Text;
    892     Server(cSetModelName, me, 0, ModelNameInfo);
     896    if ModelNameInfo.GetCommandDataSize > CommandDataMaxSize then
     897      Delete(ModelNameInfo.NewName, Length(ModelNameInfo.NewName) -
     898        (ModelNameInfo.GetCommandDataSize - 1 - CommandDataMaxSize), MaxInt);
     899    Server(CommandWithData(cSetModelName, ModelNameInfo.GetCommandDataSize),
     900      me, 0, ModelNameInfo);
    893901    if UnitStatDlg.Visible then
    894902    begin
  • trunk/LocalPlayer/Term.pas

    r435 r438  
    403403
    404404type
     405
     406  { TTribeInfo }
     407
    405408  TTribeInfo = record
    406409    trix: integer;
    407410    FileName: ShortString;
    408   end;
     411    function GetCommandDataSize: Byte;
     412  end;
     413
     414  { TCityNameInfo }
    409415
    410416  TCityNameInfo = record
    411417    ID: integer;
    412418    NewName: ShortString;
    413   end;
     419    function GetCommandDataSize: Byte;
     420  end;
     421
     422  { TModelNameInfo }
    414423
    415424  TModelNameInfo = record
    416425    mix: integer;
    417426    NewName: ShortString;
     427    function GetCommandDataSize: Byte;
    418428  end;
    419429
     
    574584  IsControl: boolean = false);
    575585procedure HelpOnTerrain(Loc: Integer; NewMode: TWindowMode);
     586function AlignUp(Value, Alignment: Integer): Integer;
    576587
    577588
     
    581592  Directories, CityScreen, Draft, MessgEx, Select, CityType, Help,
    582593  UnitStat, Log, Diagram, NatStat, Wonders, Enhance, Nego, UPixelPointer, Sound,
    583   Battle, Rates, TechTree, Registry, Global, UKeyBindings;
     594  Battle, Rates, TechTree, Registry, Global, UKeyBindings, CmdList;
    584595
    585596{$R *.lfm}
     
    760771end;
    761772
     773function AlignUp(Value, Alignment: Integer): Integer;
     774begin
     775  Result := Value or (Alignment - 1);
     776end;
     777
    762778{ *** tribe management procedures *** }
    763779
     
    812828      Tribe[p].SetModelPicture(Picture, IsNew)
    813829    else if IsNew then
    814       Server(cSetNewModelPicture, 0, 0, Picture)
     830      Server(CommandWithData(cSetNewModelPicture, Picture.GetCommandDataSize),
     831        0, 0, Picture)
    815832    else
    816       Server(cSetModelPicture, 0, 0, Picture)
     833      Server(CommandWithData(cSetModelPicture, Picture.GetCommandDataSize),
     834        0, 0, Picture)
    817835  else
    818836    with Tribe[p].ModelPicture[mix] do
     
    961979          ModelNameInfo.mix := MyData.ToldModels;
    962980          ModelNameInfo.NewName := EInput.Text;
    963           Server(cSetModelName, me, 0, ModelNameInfo);
     981          if ModelNameInfo.GetCommandDataSize > CommandDataMaxSize then
     982            Delete(ModelNameInfo.NewName, Length(ModelNameInfo.NewName) -
     983             (ModelNameInfo.GetCommandDataSize - 1 - CommandDataMaxSize), MaxInt);
     984          Server(CommandWithData(cSetModelName, ModelNameInfo.GetCommandDataSize),
     985            me, 0, ModelNameInfo);
    964986        end;
    965987      end;
     
    972994      inc(MyData.ToldModels);
    973995    end;
     996end;
     997
     998{ TTribeInfo }
     999
     1000function TTribeInfo.GetCommandDataSize: Byte;
     1001begin
     1002  Result := SizeOf(trix) + 1 + Length(FileName)
     1003end;
     1004
     1005{ TModelNameInfo }
     1006
     1007function TModelNameInfo.GetCommandDataSize: Byte;
     1008begin
     1009  Result := SizeOf(mix) + 1 + Length(NewName);
     1010end;
     1011
     1012{ TCityNameInfo }
     1013
     1014function TCityNameInfo.GetCommandDataSize: Byte;
     1015begin
     1016  Result := SizeOf(ID) + 1 + Length(NewName);
    9741017end;
    9751018
     
    27312774                CreateTribe(TribeInfo.trix, TribeInfo.FileName, false)
    27322775              else
    2733                 Server(cSetTribe, 0, 0, TribeInfo);
     2776                Server(CommandWithData(cSetTribe, TribeInfo.GetCommandDataSize),
     2777                  0, 0, TribeInfo);
    27342778            end;
    27352779
     
    27452789                CreateTribe(TribeInfo.trix, TribeInfo.FileName, false)
    27462790              else
    2747                 Server(cSetTribe, 0, 0, TribeInfo);
     2791                Server(CommandWithData(cSetTribe, TribeInfo.GetCommandDataSize),
     2792                  0, 0, TribeInfo);
    27482793            end;
    27492794        end;
     
    34453490  else
    34463491    if Command >= cClientEx then
    3447       case Command of
     3492      case Command and (not Integer(CommandDataElementCountMask)) of
    34483493        cSetTribe:
    34493494          with TTribeInfo(Data) do begin
  • trunk/LocalPlayer/Tribes.pas

    r417 r438  
    2020    yShield: Integer;
    2121  end;
     22
     23  { TModelPictureInfo }
    2224
    2325  TModelPictureInfo = record
     
    2729    Hash: Integer;
    2830    GrName: ShortString;
     31    function GetCommandDataSize: Byte;
    2932  end;
    3033
     
    283286end;
    284287
     288{ TModelPictureInfo }
     289
     290function TModelPictureInfo.GetCommandDataSize: Byte;
     291begin
     292  Result := SizeOf(trix) + SizeOf(mix) + SizeOf(pix) + SizeOf(Hash) + 1 +
     293    Length(GrName);
     294end;
     295
    285296constructor TTribe.Create(FileName: string);
    286297var
  • trunk/Log.pas

    r183 r438  
    55
    66uses
    7   LCLIntf, LCLType, LMessages, Messages, SysUtils, Classes, Graphics, Controls, Forms,
     7  LCLIntf, LCLType, Messages, SysUtils, Classes, Graphics, Controls, Forms,
    88  StdCtrls, Menus;
    99
Note: See TracChangeset for help on using the changeset viewer.