Icon View Incident Report

Serious Serious
Reported By: Elliot Byrne
Reported On: 10/12/2020
For: Version 4.49 Build 1
# 4785 Using MBCS System Locale Results in Binary BLOB Parameter Corruption for Server Procedures

We have projects which require us to run Japanese. Simply switching locale looks to have worked for most cases so far, however we have a problem backing up and then restoring a database. To outline the architecture we have a DBSupervisor which primarily does database related operations and an Editor which the User interacts with.

The user can choose to create a backup locally on their machine, this is done by calling "Backup" through a remote database connection. Basically as outlined here:

https://www.elevatesoft.com/manual?action=viewtopic&id=dbisam4&product=delphi&version=5&topic=backing_up_restoring_databases

This causes a backup file to be created on the machine running the DBSupervisor. So we then use a remote call procedure to get the DBsupervisor to load the file into memory and return the file data as the result of the procedure to the remote caller (the Editor). The editor simply saves the return data to file. So this is how we get the saved backup from the DBSupervisor machine to the Editor machine.

The problem manifests when we come to restore the file at the editor side. Basically we hit DBISAM error 9217, so the backup is corrupt! If we instead restore the file originally created by the backup mechanism on the DBSupervisor machine it restores successfully.

As a test I also tried loading the file into memory on the DBSupervisor side and then saving it out using the same function used by the Editor. When restoring that file it works successfully too. From this I would conclude that it's not out load/save logic causing the problem but passing the data through the calling procedure mechanism is corrupting the data.

Client:

procedure TForm1.Button1Click(Sender: TObject);
var
   TempFileStream: TFileStream;
begin
   with DBISAMSession1 do
      begin
      Active:=True;
      CallRemoteProcedure('StreamFile');
      TempFileStream:=TFileStream.Create('c:\temp\output.bkp',fmCreate);
      RemoteParams[0].SaveToStream(TempFileStream);
      FreeAndNil(TempFileStream);
      end;
end;

Server:

procedure TForm1.DBISAMEngine1ServerProcedure(Sender: TObject;
  ServerSession: TDBISAMSession; const ProcedureName: string);
var
   TempFileStream: TFileStream;
begin
   if SameText(ProcedureName,'StreamFile') then
      begin
      TempFileStream:=TFileStream.Create('c:\temp\input.bkp',fmOpenRead or fmShareExclusive);
      with ServerSession.RemoteParams.CreateParam(ftBlob,'BackupFile') do
         LoadFromStream(TempFileStream,ftBlob);
      FreeAndNil(TempFileStream);
      end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   with DBISAMEngine1 do
      begin
      Active:=True;
      AddServerProcedure('StreamFile','');
      AddServerProcedureUser('StreamFile','Admin',[prExecute]);
      end;
end;



Comments Comments
The issue was with the usage of AnsiStrings instead of RawByteStrings in several places related to the TDBISAMParam class used for SQL parameters and server procedure parameters.


Resolution Resolution
Fixed Problem on 10/20/2020 in version 4.49 build 2


Products Affected Products Affected
DBISAM ODBC Client-Server
DBISAM ODBC Client-Server with Source
DBISAM ODBC Standard
DBISAM ODBC Standard with Source
DBISAM ODBC Trial
DBISAM VCL Client-Server
DBISAM VCL Client-Server with Source
DBISAM VCL Standard
DBISAM VCL Standard with Source
DBISAM VCL Trial

Image