sc/inc/globstr.hrc                            |    1 +
 sc/source/ui/dataprovider/csvdataprovider.cxx |   23 ++++++++++++++++++++++-
 sc/source/ui/inc/dataprovider.hxx             |    5 +++++
 sc/source/ui/miscdlgs/dataproviderdlg.cxx     |   16 +++++++++++++++-
 4 files changed, 43 insertions(+), 2 deletions(-)

New commits:
commit 6b5d160e836772e2ebb536da10329c1d29eb4a0b
Author:     Rafael Lima <[email protected]>
AuthorDate: Tue Mar 11 19:20:51 2025 +0100
Commit:     Mike Kaganski <[email protected]>
CommitDate: Fri Mar 28 08:39:58 2025 +0100

    tdf#165658 Data Provider: Catch exception when importing CSV
    
    Currently, the DataProvider parses the CSV in a separate thread. If an 
exception happens, LO crashes or freezes.
    
    With this patch, whenever a CSV parsing error happens, it gets caught and 
an error message is shown.
    
    Change-Id: Ia7e8facfe37f22d03647d94fcdf94ae0ecae10c1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182791
    Reviewed-by: Mike Kaganski <[email protected]>
    Tested-by: Jenkins

diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index ceca2b5d31c7..c641672a7bbc 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -588,6 +588,7 @@
 #define STR_SENSITIVITY_INCREASE                
NC_("STR_SENSITIVITY_INCREASE", "Allowable Increase")
 #define STR_SENSITIVITY_SHADOWPRICE             
NC_("STR_SENSITIVITY_SHADOWPRICE", "Shadow Price")
 #define STR_SENSITIVITY_RHS                     NC_("STR_SENSITIVITY_RHS", 
"Constraint R.H. Side")
+#define STD_ERR_CSV_PARSE                       NC_("STD_ERR_CSV_PARSE", "An 
error occurred while parsing the CSV file.")
 
 #endif
 
diff --git a/sc/source/ui/dataprovider/csvdataprovider.cxx 
b/sc/source/ui/dataprovider/csvdataprovider.cxx
index 11051aab3f92..8c91aacf2ec5 100644
--- a/sc/source/ui/dataprovider/csvdataprovider.cxx
+++ b/sc/source/ui/dataprovider/csvdataprovider.cxx
@@ -10,6 +10,7 @@
 #include <dataprovider.hxx>
 #include <datatransformation.hxx>
 #include <datamapper.hxx>
+#include <exception>
 #include <stringutil.hxx>
 
 #include <tools/stream.hxx>
@@ -72,6 +73,7 @@ CSVFetchThread::CSVFetchThread(
     , mbTerminate(false)
     , maDataTransformations(std::move(rDataTransformations))
     , maImportFinishedHdl(std::move(aImportFinishedHdl))
+    , mbIsParseError(false)
 {
     maConfig.delimiters.push_back(',');
     maConfig.text_qualifier = '"';
@@ -105,7 +107,18 @@ void CSVFetchThread::execute()
 
     CSVHandler aHdl(&mrDocument);
     orcus::csv_parser<CSVHandler> parser(aBuffer, aHdl, maConfig);
-    parser.parse();
+
+    try
+    {
+        parser.parse();
+    }
+    catch(const orcus::parse_error&)
+    {
+        mbIsParseError = true;
+        mpLastException = std::current_exception();
+        RequestTerminate();
+        return;
+    }
 
     for (const auto& itr : maDataTransformations)
     {
@@ -146,6 +159,14 @@ void CSVDataProvider::Import()
     {
         SolarMutexReleaser aReleaser;
         mxCSVFetchThread->join();
+
+        // tdf#165658 An exception may have happened during the parsing of the 
file.
+        // Since parsing happens in a separate thread, here we need to check if
+        // something wrong happened and then rethrow the exception
+        if (mxCSVFetchThread->IsParseError())
+        {
+            std::rethrow_exception(mxCSVFetchThread->GetLastException());
+        }
     }
 }
 
diff --git a/sc/source/ui/inc/dataprovider.hxx 
b/sc/source/ui/inc/dataprovider.hxx
index 4647c2ba4278..4234f8df2267 100644
--- a/sc/source/ui/inc/dataprovider.hxx
+++ b/sc/source/ui/inc/dataprovider.hxx
@@ -46,6 +46,9 @@ class CSVFetchThread : public salhelper::Thread
 
     std::function<void()> maImportFinishedHdl;
 
+    std::exception_ptr mpLastException;
+    bool mbIsParseError;
+
 
 public:
     CSVFetchThread(ScDocument& rDoc, OUString , std::function<void()> 
aImportFinishedHdl,
@@ -56,6 +59,8 @@ public:
     bool IsRequestedTerminate();
     void Terminate();
     void EndThread();
+    bool IsParseError() { return mbIsParseError; }
+    auto GetLastException() { return mpLastException; }
 
     virtual void execute() override;
 };
diff --git a/sc/source/ui/miscdlgs/dataproviderdlg.cxx 
b/sc/source/ui/miscdlgs/dataproviderdlg.cxx
index a7f60a98a6bd..7d4e851c48ab 100644
--- a/sc/source/ui/miscdlgs/dataproviderdlg.cxx
+++ b/sc/source/ui/miscdlgs/dataproviderdlg.cxx
@@ -8,6 +8,8 @@
  */
 
 #include <dataproviderdlg.hxx>
+#include <scresid.hxx>
+#include <globstr.hrc>
 
 #include <document.hxx>
 #include <dataprovider.hxx>
@@ -1033,7 +1035,19 @@ void ScDataProviderDlg::import(ScDocument& rDoc, bool 
bInternal)
             return;
         rDoc.GetExternalDataMapper().insertDataSource(aSource);
     }
-    aSource.refresh(&rDoc, true);
+
+    try
+    {
+        aSource.refresh(&rDoc, true);
+    }
+    catch(const orcus::parse_error&)
+    {
+        std::unique_ptr<weld::MessageDialog> 
xMsgBox(Application::CreateMessageDialog(m_xDialog.get(),
+                                                  VclMessageType::Error, 
VclButtonsType::Close,
+                                                  ScResId(STD_ERR_CSV_PARSE)));
+        xMsgBox->run();
+    }
+
     mxTable->Invalidate();
 }
 

Reply via email to