View Issue Details

IDProjectCategoryView StatusLast Update
0036244FPCPackagespublic2019-11-02 15:46
ReporterMichal GawryckiAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.3.1Product Build 
Target VersionFixed in Version3.3.1 
Summary0036244: libxml - Invalid variables content when NO_EXTERNAL_VARS is defined
DescriptionIf NO_EXTERNAL_VARS is defined, variables xmlMalloc, xmlMallocAtomic, xmlRealloc, xmlFree and xmlMemStrdup contain invalid pointers. They point to an external variable in the libxml library but are of the procedural type in 'globals.inc' (pascal side).

See:
https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/libxml/src/globals.inc?revision=12678&view=markup#l159
https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/libxml/src/xml2.pas?revision=14126&view=markup#l275

I'm not sure how to solve this.
TagsNo tags attached.
Fixed in Revision43360
FPCOldBugId
FPCTarget3.2.0
Attached Files
  • xml2_extvars.patch (5,948 bytes)
    Index: packages/libxml/src/globals.inc
    ===================================================================
    --- packages/libxml/src/globals.inc	(revision 43356)
    +++ packages/libxml/src/globals.inc	(working copy)
    @@ -155,12 +155,39 @@
     {$ENDIF}
     
     {$ELSE} (* !LIBXML_THREAD_ALLOC_ENABLED *)
    +{$IFDEF NO_EXTERNAL_VARS}
     var
    -  xmlMalloc: xmlMallocFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
    -  xmlMallocAtomic: xmlMallocFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
    -  xmlRealloc: xmlReallocFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
    -  xmlFree: xmlFreeFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
    -  xmlMemStrdup: xmlStrdupFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
    +  varxmlMalloc: PxmlMallocFunc;
    +  varxmlMallocAtomic: PxmlMallocFunc;
    +  varxmlRealloc: PxmlReallocFunc;
    +  varxmlFree: PxmlFreeFunc;
    +  varxmlMemStrdup: PxmlStrdupFunc;
    +
    +function GetxmlMalloc: xmlMallocFunc; inline;
    +procedure SetxmlMalloc(AValue: xmlMallocFunc); inline;
    +function GetxmlMallocAtomic: xmlMallocFunc; inline;
    +procedure SetxmlMallocAtomic(AValue: xmlMallocFunc); inline;
    +function GetxmlRealloc: xmlReallocFunc; inline;
    +procedure SetxmlRealloc(AValue: xmlReallocFunc); inline;
    +function GetxmlFree: xmlFreeFunc; inline;
    +procedure SetxmlFree(AValue: xmlFreeFunc); inline;
    +function GetxmlMemStrdup: xmlStrdupFunc; inline;
    +procedure SetxmlMemStrdup(AValue: xmlStrdupFunc); inline;
    +
    +property xmlMalloc: xmlMallocFunc read GetxmlMalloc write SetxmlMalloc;
    +property xmlMallocAtomic: xmlMallocFunc read GetxmlMallocAtomic write SetxmlMallocAtomic;
    +property xmlRealloc: xmlReallocFunc read GetxmlRealloc write SetxmlRealloc;
    +property xmlFree: xmlFreeFunc read GetxmlFree write SetxmlFree;
    +property xmlMemStrdup: xmlStrdupFunc read GetxmlMemStrdup write SetxmlMemStrdup;
    +
    +{$ELSE}
    +var
    +  xmlMalloc: xmlMallocFunc; cvar; external;
    +  xmlMallocAtomic: xmlMallocFunc; cvar; external;
    +  xmlRealloc: xmlReallocFunc; cvar; external;
    +  xmlFree: xmlFreeFunc; cvar; external;
    +  xmlMemStrdup: xmlStrdupFunc; cvar; external;
    +{$ENDIF}
     {$ENDIF} (* LIBXML_THREAD_ALLOC_ENABLED *)
     
     {$IFDEF LIBXML_DOCB_ENABLED}
    Index: packages/libxml/src/xml2.pas
    ===================================================================
    --- packages/libxml/src/xml2.pas	(revision 43356)
    +++ packages/libxml/src/xml2.pas	(working copy)
    @@ -34,6 +34,58 @@
     
     implementation
     
    +{$IFDEF NO_EXTERNAL_VARS}
    +function GetxmlMalloc: xmlMallocFunc; inline;
    +begin
    +  Result := varxmlMalloc^;
    +end;
    +
    +procedure SetxmlMalloc(AValue: xmlMallocFunc); inline;
    +begin
    +  varxmlMalloc^ := AValue;
    +end;
    +
    +function GetxmlMallocAtomic: xmlMallocFunc; inline;
    +begin
    +  Result := varxmlMallocAtomic^;
    +end;
    +
    +procedure SetxmlMallocAtomic(AValue: xmlMallocFunc); inline;
    +begin
    +  varxmlMallocAtomic^ := AValue;
    +end;
    +
    +function GetxmlRealloc: xmlReallocFunc; inline;
    +begin
    +  Result := varxmlRealloc^;
    +end;
    +
    +procedure SetxmlRealloc(AValue: xmlReallocFunc); inline;
    +begin
    +  varxmlRealloc^ := AValue;
    +end;
    +
    +function GetxmlFree: xmlFreeFunc; inline;
    +begin
    +  Result := varxmlFree^;
    +end;
    +
    +procedure SetxmlFree(AValue: xmlFreeFunc); inline;
    +begin
    +  varxmlFree^ := AValue;
    +end;
    +
    +function GetxmlMemStrdup: xmlStrdupFunc; inline;
    +begin
    +  Result := varxmlMemStrdup^;
    +end;
    +
    +procedure SetxmlMemStrdup(AValue: xmlStrdupFunc); inline;
    +begin
    +  varxmlMemStrdup^ := AValue;
    +end;
    +{$ENDIF}
    +
     procedure fpcxmlFree(mem: pointer); EXTDECL;
     begin
       FreeMem(mem);
    @@ -282,11 +334,11 @@
         __xmlIsPubidChar_tab := GetProcAddress(libHandle, 'xmlIsPubidChar_tab');
         
       { globals.inc }
    -    xmlMalloc := xmlMallocFunc(GetProcAddress(libHandle, 'xmlMalloc'));
    -    xmlMallocAtomic := xmlMallocFunc(GetProcAddress(libHandle, 'xmlMallocAtomic'));
    -    xmlRealloc := xmlReallocFunc(GetProcAddress(libHandle, 'xmlRealloc'));
    -    xmlFree := xmlFreeFunc(GetProcAddress(libHandle, 'xmlFree'));
    -    xmlMemStrdup := xmlStrdupFunc(GetProcAddress(libHandle, 'xmlMemStrdup'));
    +    varxmlMalloc := PxmlMallocFunc(GetProcAddress(libHandle, 'xmlMalloc'));
    +    varxmlMallocAtomic := PxmlMallocFunc(GetProcAddress(libHandle, 'xmlMallocAtomic'));
    +    varxmlRealloc := PxmlReallocFunc(GetProcAddress(libHandle, 'xmlRealloc'));
    +    varxmlFree := PxmlFreeFunc(GetProcAddress(libHandle, 'xmlFree'));
    +    varxmlMemStrdup := PxmlStrdupFunc(GetProcAddress(libHandle, 'xmlMemStrdup'));
         
       { xpath.inc }
        {__xmlXPathNAN := PDouble(GetProcAddress(libHandle, 'xmlXPathNAN'));
    Index: packages/libxml/src/xmlmemory.inc
    ===================================================================
    --- packages/libxml/src/xmlmemory.inc	(revision 43356)
    +++ packages/libxml/src/xmlmemory.inc	(working copy)
    @@ -45,6 +45,9 @@
      * Signature for a free() implementation.
      *)
       xmlFreeFunc = procedure(mem: pointer); EXTDECL;
    +  {$IFDEF NO_EXTERNAL_VARS}
    +  PxmlFreeFunc = ^xmlFreeFunc;
    +  {$ENDIF}
     
     (**
      * xmlMallocFunc:
    @@ -55,6 +58,9 @@
      * Returns a pointer to the newly allocated block or NULL in case of error.
      *)
       xmlMallocFunc = function(size: csize_t): pointer; EXTDECL;
    +  {$IFDEF NO_EXTERNAL_VARS}
    +  PxmlMallocFunc = ^xmlMallocFunc;
    +  {$ENDIF}
     
     (**
      * xmlReallocFunc:
    @@ -66,6 +72,9 @@
      * Returns a pointer to the newly reallocated block or NULL in case of error.
      *)
       xmlReallocFunc = function(mem: pointer; size: csize_t): pointer; EXTDECL;
    +  {$IFDEF NO_EXTERNAL_VARS}
    +  PxmlReallocFunc = ^xmlReallocFunc;
    +  {$ENDIF}
     
     (**
      * xmlStrdupFunc:
    @@ -76,6 +85,9 @@
      * Returns the copy of the string or NULL in case of error.
      *)
       xmlStrdupFunc = function(str: pchar): pchar; EXTDECL;
    +  {$IFDEF NO_EXTERNAL_VARS}
    +  PxmlStrdupFunc = ^xmlStrdupFunc;
    +  {$ENDIF}
     
     (*
      * The 4 interfaces used for all memory handling within libxml.
    @@ -170,4 +182,4 @@
     //#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
     
     {$ENDIF} (* DEBUG_MEMORY_LOCATION *)
    -{$ENDIF}
    \ No newline at end of file
    +{$ENDIF}
    
    xml2_extvars.patch (5,948 bytes)

Activities

Michael Van Canneyt

2019-11-02 11:44

administrator   ~0118973

Assuming these variables contain a function pointer, try changing the relevant code in LoadExternalVariables with this:

    xmlMalloc := xmlMallocFunc(PPointer(GetProcAddress(libHandle, 'xmlMalloc'))^);
    xmlMallocAtomic := xmlMallocFunc(PPointer(GetProcAddress(libHandle, 'xmlMallocAtomic'))^);
    xmlRealloc := xmlReallocFunc(PPointer(GetProcAddress(libHandle, 'xmlRealloc'))^);
    xmlFree := xmlFreeFunc(PPointer(GetProcAddress(libHandle, 'xmlFree'))^);
    xmlMemStrdup := xmlStrdupFunc(PPointer(GetProcAddress(libHandle, 'xmlMemStrdup'))^);

I have no test program so I can't really test myself.

Michal Gawrycki

2019-11-02 12:56

reporter   ~0118978

We still get current variable content when calling GetProcAddress. In addition, changing the values of variables from the pascal side does not change them in libxml. I think the solution would be to introduce getters an setters.
Patch attached.

xml2_extvars.patch (5,948 bytes)
Index: packages/libxml/src/globals.inc
===================================================================
--- packages/libxml/src/globals.inc	(revision 43356)
+++ packages/libxml/src/globals.inc	(working copy)
@@ -155,12 +155,39 @@
 {$ENDIF}
 
 {$ELSE} (* !LIBXML_THREAD_ALLOC_ENABLED *)
+{$IFDEF NO_EXTERNAL_VARS}
 var
-  xmlMalloc: xmlMallocFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
-  xmlMallocAtomic: xmlMallocFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
-  xmlRealloc: xmlReallocFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
-  xmlFree: xmlFreeFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
-  xmlMemStrdup: xmlStrdupFunc; {$IFNDEF NO_EXTERNAL_VARS}cvar; external;{$ENDIF}
+  varxmlMalloc: PxmlMallocFunc;
+  varxmlMallocAtomic: PxmlMallocFunc;
+  varxmlRealloc: PxmlReallocFunc;
+  varxmlFree: PxmlFreeFunc;
+  varxmlMemStrdup: PxmlStrdupFunc;
+
+function GetxmlMalloc: xmlMallocFunc; inline;
+procedure SetxmlMalloc(AValue: xmlMallocFunc); inline;
+function GetxmlMallocAtomic: xmlMallocFunc; inline;
+procedure SetxmlMallocAtomic(AValue: xmlMallocFunc); inline;
+function GetxmlRealloc: xmlReallocFunc; inline;
+procedure SetxmlRealloc(AValue: xmlReallocFunc); inline;
+function GetxmlFree: xmlFreeFunc; inline;
+procedure SetxmlFree(AValue: xmlFreeFunc); inline;
+function GetxmlMemStrdup: xmlStrdupFunc; inline;
+procedure SetxmlMemStrdup(AValue: xmlStrdupFunc); inline;
+
+property xmlMalloc: xmlMallocFunc read GetxmlMalloc write SetxmlMalloc;
+property xmlMallocAtomic: xmlMallocFunc read GetxmlMallocAtomic write SetxmlMallocAtomic;
+property xmlRealloc: xmlReallocFunc read GetxmlRealloc write SetxmlRealloc;
+property xmlFree: xmlFreeFunc read GetxmlFree write SetxmlFree;
+property xmlMemStrdup: xmlStrdupFunc read GetxmlMemStrdup write SetxmlMemStrdup;
+
+{$ELSE}
+var
+  xmlMalloc: xmlMallocFunc; cvar; external;
+  xmlMallocAtomic: xmlMallocFunc; cvar; external;
+  xmlRealloc: xmlReallocFunc; cvar; external;
+  xmlFree: xmlFreeFunc; cvar; external;
+  xmlMemStrdup: xmlStrdupFunc; cvar; external;
+{$ENDIF}
 {$ENDIF} (* LIBXML_THREAD_ALLOC_ENABLED *)
 
 {$IFDEF LIBXML_DOCB_ENABLED}
Index: packages/libxml/src/xml2.pas
===================================================================
--- packages/libxml/src/xml2.pas	(revision 43356)
+++ packages/libxml/src/xml2.pas	(working copy)
@@ -34,6 +34,58 @@
 
 implementation
 
+{$IFDEF NO_EXTERNAL_VARS}
+function GetxmlMalloc: xmlMallocFunc; inline;
+begin
+  Result := varxmlMalloc^;
+end;
+
+procedure SetxmlMalloc(AValue: xmlMallocFunc); inline;
+begin
+  varxmlMalloc^ := AValue;
+end;
+
+function GetxmlMallocAtomic: xmlMallocFunc; inline;
+begin
+  Result := varxmlMallocAtomic^;
+end;
+
+procedure SetxmlMallocAtomic(AValue: xmlMallocFunc); inline;
+begin
+  varxmlMallocAtomic^ := AValue;
+end;
+
+function GetxmlRealloc: xmlReallocFunc; inline;
+begin
+  Result := varxmlRealloc^;
+end;
+
+procedure SetxmlRealloc(AValue: xmlReallocFunc); inline;
+begin
+  varxmlRealloc^ := AValue;
+end;
+
+function GetxmlFree: xmlFreeFunc; inline;
+begin
+  Result := varxmlFree^;
+end;
+
+procedure SetxmlFree(AValue: xmlFreeFunc); inline;
+begin
+  varxmlFree^ := AValue;
+end;
+
+function GetxmlMemStrdup: xmlStrdupFunc; inline;
+begin
+  Result := varxmlMemStrdup^;
+end;
+
+procedure SetxmlMemStrdup(AValue: xmlStrdupFunc); inline;
+begin
+  varxmlMemStrdup^ := AValue;
+end;
+{$ENDIF}
+
 procedure fpcxmlFree(mem: pointer); EXTDECL;
 begin
   FreeMem(mem);
@@ -282,11 +334,11 @@
     __xmlIsPubidChar_tab := GetProcAddress(libHandle, 'xmlIsPubidChar_tab');
     
   { globals.inc }
-    xmlMalloc := xmlMallocFunc(GetProcAddress(libHandle, 'xmlMalloc'));
-    xmlMallocAtomic := xmlMallocFunc(GetProcAddress(libHandle, 'xmlMallocAtomic'));
-    xmlRealloc := xmlReallocFunc(GetProcAddress(libHandle, 'xmlRealloc'));
-    xmlFree := xmlFreeFunc(GetProcAddress(libHandle, 'xmlFree'));
-    xmlMemStrdup := xmlStrdupFunc(GetProcAddress(libHandle, 'xmlMemStrdup'));
+    varxmlMalloc := PxmlMallocFunc(GetProcAddress(libHandle, 'xmlMalloc'));
+    varxmlMallocAtomic := PxmlMallocFunc(GetProcAddress(libHandle, 'xmlMallocAtomic'));
+    varxmlRealloc := PxmlReallocFunc(GetProcAddress(libHandle, 'xmlRealloc'));
+    varxmlFree := PxmlFreeFunc(GetProcAddress(libHandle, 'xmlFree'));
+    varxmlMemStrdup := PxmlStrdupFunc(GetProcAddress(libHandle, 'xmlMemStrdup'));
     
   { xpath.inc }
    {__xmlXPathNAN := PDouble(GetProcAddress(libHandle, 'xmlXPathNAN'));
Index: packages/libxml/src/xmlmemory.inc
===================================================================
--- packages/libxml/src/xmlmemory.inc	(revision 43356)
+++ packages/libxml/src/xmlmemory.inc	(working copy)
@@ -45,6 +45,9 @@
  * Signature for a free() implementation.
  *)
   xmlFreeFunc = procedure(mem: pointer); EXTDECL;
+  {$IFDEF NO_EXTERNAL_VARS}
+  PxmlFreeFunc = ^xmlFreeFunc;
+  {$ENDIF}
 
 (**
  * xmlMallocFunc:
@@ -55,6 +58,9 @@
  * Returns a pointer to the newly allocated block or NULL in case of error.
  *)
   xmlMallocFunc = function(size: csize_t): pointer; EXTDECL;
+  {$IFDEF NO_EXTERNAL_VARS}
+  PxmlMallocFunc = ^xmlMallocFunc;
+  {$ENDIF}
 
 (**
  * xmlReallocFunc:
@@ -66,6 +72,9 @@
  * Returns a pointer to the newly reallocated block or NULL in case of error.
  *)
   xmlReallocFunc = function(mem: pointer; size: csize_t): pointer; EXTDECL;
+  {$IFDEF NO_EXTERNAL_VARS}
+  PxmlReallocFunc = ^xmlReallocFunc;
+  {$ENDIF}
 
 (**
  * xmlStrdupFunc:
@@ -76,6 +85,9 @@
  * Returns the copy of the string or NULL in case of error.
  *)
   xmlStrdupFunc = function(str: pchar): pchar; EXTDECL;
+  {$IFDEF NO_EXTERNAL_VARS}
+  PxmlStrdupFunc = ^xmlStrdupFunc;
+  {$ENDIF}
 
 (*
  * The 4 interfaces used for all memory handling within libxml.
@@ -170,4 +182,4 @@
 //#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
 
 {$ENDIF} (* DEBUG_MEMORY_LOCATION *)
-{$ENDIF}
\ No newline at end of file
+{$ENDIF}
xml2_extvars.patch (5,948 bytes)

Michael Van Canneyt

2019-11-02 14:08

administrator   ~0118979

Looks good. Applied. Please test and close if OK.

Michal Gawrycki

2019-11-02 15:19

reporter   ~0118981

Hi, Michael.
Revision 43360 contains only changes in xml2.pas, but there are no changes in globals.inc and xmlmemory.inc.

Michael Van Canneyt

2019-11-02 15:34

administrator   ~0118982

Sorry, forgot to commit 2 files. Please test and close if OK

Michal Gawrycki

2019-11-02 15:46

reporter   ~0118985

Tested. Thanks, closed.

Issue History

Date Modified Username Field Change
2019-11-01 18:29 Michal Gawrycki New Issue
2019-11-02 11:44 Michael Van Canneyt Assigned To => Michael Van Canneyt
2019-11-02 11:44 Michael Van Canneyt Status new => feedback
2019-11-02 11:44 Michael Van Canneyt FPCTarget => -
2019-11-02 11:44 Michael Van Canneyt Note Added: 0118973
2019-11-02 12:56 Michal Gawrycki File Added: xml2_extvars.patch
2019-11-02 12:56 Michal Gawrycki Note Added: 0118978
2019-11-02 12:56 Michal Gawrycki Status feedback => assigned
2019-11-02 14:08 Michael Van Canneyt Status assigned => resolved
2019-11-02 14:08 Michael Van Canneyt Resolution open => fixed
2019-11-02 14:08 Michael Van Canneyt Fixed in Version => 3.3.1
2019-11-02 14:08 Michael Van Canneyt Fixed in Revision => 43360
2019-11-02 14:08 Michael Van Canneyt FPCTarget - => 3.2.0
2019-11-02 14:08 Michael Van Canneyt Note Added: 0118979
2019-11-02 15:19 Michal Gawrycki Status resolved => feedback
2019-11-02 15:19 Michal Gawrycki Resolution fixed => reopened
2019-11-02 15:19 Michal Gawrycki Note Added: 0118981
2019-11-02 15:34 Michael Van Canneyt Status feedback => resolved
2019-11-02 15:34 Michael Van Canneyt Resolution reopened => fixed
2019-11-02 15:34 Michael Van Canneyt Note Added: 0118982
2019-11-02 15:46 Michal Gawrycki Status resolved => closed
2019-11-02 15:46 Michal Gawrycki Note Added: 0118985