desktop/source/lib/init.cxx               |    1 +
 include/LibreOfficeKit/LibreOfficeKit.h   |   14 ++++++++++++++
 include/LibreOfficeKit/LibreOfficeKit.hxx |   21 ++++++++++++++++++++-
 3 files changed, 35 insertions(+), 1 deletion(-)

New commits:
commit c80eb9ff9a94899dcc582c0d85f8ed94c8c91cad
Author:     Tor Lillqvist <[email protected]>
AuthorDate: Fri Jul 11 16:19:11 2025 +0300
Commit:     Michael Stahl <[email protected]>
CommitDate: Tue Dec 2 10:14:06 2025 +0100

    Clarify that freeError() despite its name is a generic LOKit deallocation 
API
    
    Especially on Windows it is important to not call free() in your own
    code on a pointer returned from some random other dynamic library
    (like the one the desktop/source/lib/init.cxx code goes into). It
    might have been allocated by calling malloc() (etc) in a C runtime
    library that is different from the one used by your code. That will
    lead to a crash.
    
    One should alays call the free() in the same C runtime where the
    malloc() that allocated the pointer is.
    
    Add a wrapper called freeMemory() to the C++ API.
    
    Change-Id: Ibf9cf6fad2c30c4416d2a1f6badbd161c7ba18a6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194594
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 7cd8ad4c28ff..480f0733223b 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -7756,6 +7756,7 @@ static char* lo_getError (LibreOfficeKit *pThis)
 
 static void lo_freeError(char* pFree)
 {
+    // Do not try to do anything clever here. This should just call free() on 
the pointer.
     free(pFree);
 }
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h 
b/include/LibreOfficeKit/LibreOfficeKit.h
index 7860adf3c66b..8d6ec5fa2646 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -65,6 +65,20 @@ struct _LibreOfficeKitClass
                                                         const char* pURL,
                                                         const char* pOptions);
     /// @since LibreOffice 5.2
+
+    /// The name "freeError" is a historical accident, actually this
+    /// is a generic deallocation function for dynamically allocated
+    /// memory returned by other LibreOfficeKit functions.
+
+    /// Especially on Windows it is important to not call free() in
+    /// your own code on a pointer returned from some random other
+    /// dynamic library (like the one this code goes into) where it
+    /// might have been allocated by calling malloc() (etc) in a C
+    /// runtime library that is different from the one used by your
+    /// code. That will lead to a crash. Alays call the free() in the
+    /// same C runtime where the malloc() that allocated the pointer
+    /// is.
+
     void (*freeError) (char* pFree);
 
     /// @since LibreOffice 6.0
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx 
b/include/LibreOfficeKit/LibreOfficeKit.hxx
index b6cdd929cb95..77facfb1867f 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -486,6 +486,9 @@ public:
      * e.g. {commandName: ".uno:StyleApply", commandValues: {"familyName1" : 
["list of style names in the family1"], etc.}}
      * @param pCommand a UNO command for which the possible values are 
requested
      * @return {commandName: unoCmd, commandValues: {possible_values}}
+     *
+     * The return value is dynamically allocated and should be
+     * deallocated by calling the lok::Office::freeMemory() function.
      */
     char* getCommandValues(const char* pCommand)
     {
@@ -1009,7 +1012,8 @@ public:
         return new Document(pDoc);
     }
 
-    /// Returns the last error as a string, the returned pointer has to be 
freed by the caller.
+    /// Returns the last error as a string. The returned pointer has to be 
freed by the caller
+    /// by calling the freeError() member function.
     char* getError()
     {
         return mpThis->pClass->getError(mpThis);
@@ -1018,6 +1022,10 @@ public:
     /**
      * Frees the memory pointed to by pFree.
      *
+     * Use on dynamically allocated data returned by LibreOfficeKit
+     * functions. In other cases than the value returned by
+     * getError(), call freeMemory() instead for clarity.
+     *
      * @since LibreOffice 5.2
      */
     void freeError(char* pFree)
@@ -1316,6 +1324,17 @@ public:
     {
         return mpThis->pClass->getDocsCount(mpThis);
     }
+
+    /**
+     * Frees the memory pointed to by pFree.
+     *
+     * Use on dynamically allocated data returned by LibreOfficeKit
+     * functions. Just a wrapper for freeError() with a better name.
+     */
+    void freeMemory(char* pFree)
+    {
+        freeError(pFree);
+    }
 };
 
 /// Factory method to create a lok::Office instance.

Reply via email to