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 aad13413e5448de92816957bead2b9008d92d5f7
Author:     Tor Lillqvist <[email protected]>
AuthorDate: Fri Jul 11 16:19:11 2025 +0300
Commit:     Tor Lillqvist <[email protected]>
CommitDate: Tue Jan 13 15:31:47 2026 +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]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197107
    Tested-by: Jenkins
    Reviewed-by: Tor Lillqvist <[email protected]>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index a4349cba2b0c..2ad2db58e381 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -7799,6 +7799,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 e49cdf174892..4c94cb6041ad 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 fae2b0de7c84..6654a83587dc 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)
@@ -1317,6 +1325,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);
+    }
+
     /**
      * Registers a callback that can display an interactive file save dialog.
      */

Reply via email to