diff --git a/reportdesign/qa/unit/ReportDesignBasicTests.cxx b/reportdesign/qa/unit/ReportDesignBasicTests.cxx index 628585a472cf..2e475e22ee20 100644 --- a/reportdesign/qa/unit/ReportDesignBasicTests.cxx +++ b/reportdesign/qa/unit/ReportDesignBasicTests.cxx @@ -25,6 +25,10 @@ #include #include #include +#include +#include +#include +#include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -173,6 +177,45 @@ CPPUNIT_TEST_FIXTURE(RptBasicTest, nestedGroupBoundary) nPentahoHeaders, nCppHeaders); } +CPPUNIT_TEST_FIXTURE(RptBasicTest, emptyCommandNoCrash) +{ + // Executing a report with no Command (query/table) set must fail cleanly + // (IllegalArgumentException) under the C++ ReportBuilder path, same as the + // Pentaho path already does - not reach the undefined behavior that used to + // sit behind an unguarded empty-column-list access in getColumnNameString(). + loadURLCopy(u"nested_group_boundary.odb"); + + Reference xModel(mxComponent, UNO_QUERY_THROW); + Reference xController(xModel->getCurrentController()); + Reference xUI(xController, UNO_QUERY_THROW); + + xUI->connect(); + Reference xActiveConnection = xUI->getActiveConnection(); + + Reference xSupp(xModel, UNO_QUERY_THROW); + Reference xNameAccess = xSupp->getReportDocuments(); + const Sequence aReportNames(xNameAccess->getElementNames()); + CPPUNIT_ASSERT(aReportNames.hasElements()); + + Reference xSubDoc(xNameAccess->getByName(aReportNames[0]), UNO_QUERY_THROW); + Reference xReportDef(xSubDoc->openDesign(), UNO_QUERY_THROW); + xReportDef->setCommand(u""_ustr); + xSubDoc->store(); + xSubDoc->close(); + + const OUString sVarName(u"SAL_ENABLE_PENTAHO_FREE_REPORTBUILDER"_ustr); + osl_setEnvironment(sVarName.pData, u"1"_ustr.pData); + comphelper::ScopeGuard aEnvGuard([&sVarName] { osl_clearEnvironment(sVarName.pData); }); + + ::comphelper::NamedValueCollection aLoadArgs; + aLoadArgs.put(u"ActiveConnection"_ustr, xActiveConnection); + Reference xComponentLoader(xNameAccess, UNO_QUERY_THROW); + + CPPUNIT_ASSERT_THROW(xComponentLoader->loadComponentFromURL(aReportNames[0], u"_blank"_ustr, 0, + aLoadArgs.getPropertyValues()), + lang::IllegalArgumentException); +} + OUString RptBasicTest::renderReportText(const OUString& rReportName, const Reference& xComponentLoader, const Reference& xActiveConnection, @@ -183,6 +226,7 @@ OUString RptBasicTest::renderReportText(const OUString& rReportName, osl_setEnvironment(sVarName.pData, u"1"_ustr.pData); else osl_clearEnvironment(sVarName.pData); + comphelper::ScopeGuard aEnvGuard([&sVarName] { osl_clearEnvironment(sVarName.pData); }); ::comphelper::NamedValueCollection aLoadArgs; aLoadArgs.put(u"ActiveConnection"_ustr, xActiveConnection); @@ -190,8 +234,6 @@ OUString RptBasicTest::renderReportText(const OUString& rReportName, Reference xComponent = xComponentLoader->loadComponentFromURL( rReportName, u"_blank"_ustr, 0, aLoadArgs.getPropertyValues()); - osl_clearEnvironment(sVarName.pData); - Reference xTextDoc(xComponent, UNO_QUERY_THROW); OUStringBuffer sText(xTextDoc->getText()->getString()); diff --git a/reportdesign/source/core/api/ReportEngineJFree.cxx b/reportdesign/source/core/api/ReportEngineJFree.cxx index 8481173208f6..9619d9426d23 100644 --- a/reportdesign/source/core/api/ReportEngineJFree.cxx +++ b/reportdesign/source/core/api/ReportEngineJFree.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -199,11 +200,15 @@ OUString OReportEngineJFree::getNewOutputName() if (bCppReportBuilder) { // C++ ReportBuilder path: uses ORptExecuteExport for direct export with data - m_pReport->setUseRPTTags(false); - m_pReport->storeToStorage(xOut, aEmpty); - m_pReport->setUseRPTTags(true); - if ( xStorageProp.is() ) - sOutputName = sFileURL; + if (!m_pReport->getCommand().isEmpty()) + { + m_pReport->setUseRPTTags(false); + comphelper::ScopeGuard aRestoreRPTTags( + [this]() { m_pReport->setUseRPTTags(true); }); + m_pReport->storeToStorage(xOut, aEmpty); + if ( xStorageProp.is() ) + sOutputName = sFileURL; + } } else { diff --git a/reportdesign/source/filter/xml/xmlExport2.cxx b/reportdesign/source/filter/xml/xmlExport2.cxx index e5ac5fd4b776..80590a9e7764 100644 --- a/reportdesign/source/filter/xml/xmlExport2.cxx +++ b/reportdesign/source/filter/xml/xmlExport2.cxx @@ -654,6 +654,8 @@ ORptExecuteExport::getColumnNameString(const Reference& _xRep _xReportDefinition->getCommand(), xHoldAlive); OUString sColumnNameList; Sequence sColumnNames = xColumns->getElementNames(); + if (!sColumnNames.hasElements()) + return sColumnNameList; for (sal_Int32 i = 0; i < sColumnNames.getLength() - 1; i++) {