mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
FIX #1680: Internal Viewer crashes on macOS
in FPC 3.2.2, there are some bugs in Iconvert().
use the fixed Iconvert() instead of the FPC version on macOS.
(cherry picked from commit 01c8c0c81b)
This commit is contained in:
parent
fbf2075bf8
commit
5f8ddd0e6c
5 changed files with 190 additions and 21 deletions
|
|
@ -68,11 +68,11 @@ implementation
|
|||
|
||||
uses
|
||||
{$IF DEFINED(UNIX)}
|
||||
iconvenc_dyn, LazUTF8
|
||||
LazUTF8
|
||||
{$IF DEFINED(DARWIN)}
|
||||
, MacOSAll, CocoaAll, StrUtils
|
||||
, dc_iconvenc_dyn, MacOSAll, CocoaAll, StrUtils
|
||||
{$ELSE}
|
||||
, UnixCP
|
||||
, iconvenc_dyn, UnixCP
|
||||
{$ENDIF}
|
||||
{$ELSEIF DEFINED(MSWINDOWS)}
|
||||
Windows
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="iconvenc"/>
|
||||
<OtherUnitFiles Value="iconvenc"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Conditionals Value="if (TargetCPU <> 'arm') then
|
||||
|
|
@ -35,7 +37,7 @@ end"/>
|
|||
<Description Value="Common units for Double Commander"/>
|
||||
<License Value="GNU GPL 2"/>
|
||||
<Version Minor="4" Release="1"/>
|
||||
<Files Count="12">
|
||||
<Files Count="14">
|
||||
<Item1>
|
||||
<Filename Value="dcclassesutf8.pas"/>
|
||||
<UnitName Value="DCClassesUtf8"/>
|
||||
|
|
@ -84,6 +86,14 @@ end"/>
|
|||
<Filename Value="dcjsonconfig.pas"/>
|
||||
<UnitName Value="DCJsonConfig"/>
|
||||
</Item12>
|
||||
<Item13>
|
||||
<Filename Value="iconvenc\dc_iconvert.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item13>
|
||||
<Item14>
|
||||
<Filename Value="iconvenc\dc_iconvenc_dyn.pas"/>
|
||||
<UnitName Value="dc_iconvenc_dyn"/>
|
||||
</Item14>
|
||||
</Files>
|
||||
<CompatibilityMode Value="True"/>
|
||||
<RequiredPkgs Count="2">
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit doublecmd_common;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
uses
|
||||
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
|
||||
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
|
||||
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit doublecmd_common;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
uses
|
||||
DCClassesUtf8, DCOSUtils, DCStrUtils, DCBasicTypes, DCFileAttributes,
|
||||
DCConvertEncoding, DCDateTimeUtils, DCXmlConfig, DCProcessUtf8,
|
||||
DCUnicodeUtils, DCStringHashListUtf8, DCJsonConfig, dc_iconvenc_dyn;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
|
|||
106
components/doublecmd/iconvenc/dc_iconvenc_dyn.pas
Normal file
106
components/doublecmd/iconvenc/dc_iconvenc_dyn.pas
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
{
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 2000 by Marco van de Voort(marco@freepascal.org)
|
||||
member of the Free Pascal development team
|
||||
|
||||
libiconv header translation + a helper routine
|
||||
http://wiki.freepascal.org/iconvenc Dynamic version
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright. (LGPL)
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
}
|
||||
unit dc_iconvenc_dyn;
|
||||
|
||||
interface
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
ctypes,unixtype,baseunix,
|
||||
dl,
|
||||
initc;
|
||||
|
||||
const
|
||||
n = 1;
|
||||
|
||||
{$ifdef beos}
|
||||
ESysEILSEQ = EILSEQ;
|
||||
{$endif}
|
||||
|
||||
type
|
||||
piconv_t = ^iconv_t;
|
||||
iconv_t = pointer;
|
||||
|
||||
Ticonv_open = function(__tocode: pchar; __fromcode: pchar): iconv_t; cdecl;
|
||||
Ticonv = function(__cd: iconv_t; __inbuf: ppchar; __inbytesleft: psize_t; __outbuf: ppchar; __outbytesleft: psize_t): size_t; cdecl;
|
||||
Ticonv_close = function(__cd: iconv_t): cint; cdecl;
|
||||
|
||||
var
|
||||
iconv_lib: pointer;
|
||||
iconv_open: Ticonv_open;
|
||||
iconv: Ticonv;
|
||||
iconv_close: Ticonv_close;
|
||||
IconvLibFound: boolean = False;
|
||||
|
||||
function TryLoadLib(LibName: string; var error: string): boolean; // can be used to load non standard libname
|
||||
function Iconvert(s: string; var res: string; const FromEncoding, ToEncoding: string): cint;
|
||||
function InitIconv(var error: string): boolean;
|
||||
|
||||
implementation
|
||||
|
||||
function TryLoadLib(LibName: string; var error: string): boolean;
|
||||
|
||||
function resolvesymbol (var funcptr; symbol: string): Boolean;
|
||||
begin
|
||||
pointer(funcptr) := pointer(dlsym(iconv_lib, pchar(symbol)));
|
||||
result := assigned(pointer(funcptr));
|
||||
if not result then
|
||||
error := error+#13#10+dlerror();
|
||||
end;
|
||||
|
||||
var
|
||||
res: boolean;
|
||||
begin
|
||||
result := false;
|
||||
Error := Error+#13#10'Trying '+LibName;
|
||||
iconv_lib := dlopen(pchar(libname), RTLD_NOW);
|
||||
if Assigned(iconv_lib) then
|
||||
begin
|
||||
result := true;
|
||||
result := result and resolvesymbol(pointer(iconv),'iconv');
|
||||
result := result and resolvesymbol(pointer(iconv_open),'iconv_open');
|
||||
result := result and resolvesymbol(pointer(iconv_close),'iconv_close');
|
||||
if not result then
|
||||
begin
|
||||
result:=true;
|
||||
result := result and resolvesymbol(pointer(iconv),'libiconv');
|
||||
result := result and resolvesymbol(pointer(iconv_open),'libiconv_open');
|
||||
result := result and resolvesymbol(pointer(iconv_close),'libiconv_close');
|
||||
end;
|
||||
// if not res then
|
||||
// dlclose(iconv_lib);
|
||||
end else
|
||||
error:=error+#13#10+dlerror();
|
||||
end;
|
||||
|
||||
|
||||
function InitIconv(var error: string): boolean;
|
||||
begin
|
||||
result := true;
|
||||
error := '';
|
||||
if not TryLoadLib('libc.so.6', error) then
|
||||
if not TryLoadLib('libiconv.so', error) then
|
||||
{$if defined(haiku)}
|
||||
if not TryLoadLib('libtextencoding.so', error) then
|
||||
{$ifend}
|
||||
result := false;
|
||||
iconvlibfound := iconvlibfound or result;
|
||||
end;
|
||||
|
||||
{$i dc_iconvert.inc}
|
||||
|
||||
end.
|
||||
53
components/doublecmd/iconvenc/dc_iconvert.inc
Normal file
53
components/doublecmd/iconvenc/dc_iconvert.inc
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
function Iconvert(S: string; var Res: string; const FromEncoding, ToEncoding: string): cint;
|
||||
var
|
||||
InLen, OutLen, Offset: size_t;
|
||||
Src, Dst: pchar;
|
||||
H: iconv_t;
|
||||
lerr: cint;
|
||||
iconvres: size_t;
|
||||
begin
|
||||
H := iconv_open(PChar(ToEncoding), PChar(FromEncoding));
|
||||
if h=Iconv_t(-1) then
|
||||
begin
|
||||
Res := S;
|
||||
exit(-1);
|
||||
end;
|
||||
|
||||
try
|
||||
InLen:=Length(s);
|
||||
outlen:=InLen;
|
||||
setlength(res,outlen);
|
||||
|
||||
Src := PChar(S);
|
||||
Dst := PChar(Res);
|
||||
|
||||
while InLen > 0 do
|
||||
begin
|
||||
iconvres := iconv(H, @Src, @InLen, @Dst, @OutLen);
|
||||
if iconvres = size_t(-1) then
|
||||
begin
|
||||
lerr := cerrno;
|
||||
if lerr = ESysEILSEQ then // unknown char, skip
|
||||
begin
|
||||
Inc(Src);
|
||||
Dec(InLen);
|
||||
end
|
||||
else
|
||||
if lerr = ESysE2BIG then
|
||||
begin
|
||||
Offset := Dst - PChar(Res);
|
||||
SetLength(Res, Length(Res)+InLen*2+5); // 5 is minimally one utf-8 char
|
||||
Dst := PChar(Res) + Offset;
|
||||
OutLen := Length(Res) - Offset;
|
||||
end
|
||||
else
|
||||
exit(-1)
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
setlength(Res,Length(Res) - Outlen);
|
||||
iconv_close(H);
|
||||
end;
|
||||
|
||||
Result := 0;
|
||||
end;
|
||||
Loading…
Add table
Add a link
Reference in a new issue