[education/rkward] rkward: Fix crash when type of edited column gets changed to an unknown type

Thomas Friedrichsmeier null at kde.org
Thu Jul 10 18:08:48 BST 2025


Git commit dfac743c6e8894ea8383ee5be939d9e87283d8e5 by Thomas Friedrichsmeier.
Committed on 10/07/2025 at 17:06.
Pushed by tfry into branch 'master'.

Fix crash when type of edited column gets changed to an unknown type

CCBUG: 50955

M  +10   -1    rkward/autotests/core_test.cpp
M  +5    -2    rkward/core/rkvariable.cpp

https://invent.kde.org/education/rkward/-/commit/dfac743c6e8894ea8383ee5be939d9e87283d8e5

diff --git a/rkward/autotests/core_test.cpp b/rkward/autotests/core_test.cpp
index 8bb48faf3..cd5196dfc 100644
--- a/rkward/autotests/core_test.cpp
+++ b/rkward/autotests/core_test.cpp
@@ -544,7 +544,16 @@ class RKWardCoreTest : public QObject {
 		RInterface::issueCommand(new RCommand(QStringLiteral("df <- data.frame('a'=letters, 'a'=letters, 'b'=letters, check.names=FALSE); df[[2, 'b']] <- list('x')"), RCommand::User));
 		RInterface::issueCommand(new RCommand(QStringLiteral("rk.edit(df)"), RCommand::User));
 		waitForAllFinished();
-		RKWardMainWindow::getMain()->slotCloseAllEditors();
+
+		// https://bugs.kde.org/show_bug.cgi?id=505955 : crash when changing type of edited column to unknown from R
+		RInterface::issueCommand(new RCommand(QStringLiteral("df$c <- 1"), RCommand::User));
+		waitForAllFinished();
+		RInterface::issueCommand(new RCommand(QStringLiteral("df$c <- as.POSIXct.Date(1)"), RCommand::User)); // this one is current "unknown"
+		waitForAllFinished();
+		RInterface::issueCommand(new RCommand(QStringLiteral("df$c <- as.factor(\"a\")"), RCommand::User));
+		waitForAllFinished();
+
+		RKWardMainWindow::getMain()->slotCloseAllEditors();		
 	}
 
 	void rkMenuTest() {
diff --git a/rkward/core/rkvariable.cpp b/rkward/core/rkvariable.cpp
index fdb3969c4..afe6d87fe 100644
--- a/rkward/core/rkvariable.cpp
+++ b/rkward/core/rkvariable.cpp
@@ -122,14 +122,17 @@ bool RKVariable::updateType(RData *new_data) {
 	if (data) {
 		int old_type = type;
 		bool ret = RObject::updateType(new_data);
-		int new_type = type;
+		if (old_type == type) return ret;
 
 		// Convert old values to the new data type.
 		// TODO: This is quite inefficient, as we will update the data from R in a second, anyway.
 		// Still it is a quick, dirty, and safe way to keep the data representation in a suitable format
+		int new_type = type;
 		type = old_type; // needed to read out the old data
 		setVarType(typeToDataType(new_type), false);
+		auto datatype = getDataType(); // HACK: setVarType might have changed the type. We still want to apply any other flags from R
 		type = new_type;
+		setDataType(datatype);
 		return ret;
 	}
 	return RObject::updateType(new_data);
@@ -551,7 +554,7 @@ void RKVariable::setNumericFromR(int from_row, int to_row, const QVector<double>
 	RK_ASSERT((to_row - from_row) < numdata.size());
 
 	if (getDataType() == DataCharacter) {
-		RK_ASSERT(false); // asserting false to catch cases of this use for now. it's not really a problem, though
+		// NOTE: This code path is hit, for data this somehow numeric in R, but "unknown" in the frontend (fallback in setVarType())
 		int i = 0;
 		for (int row = from_row; row <= to_row; ++row) {
 			setText(row, QString::number(numdata[i++], 'g', MAX_PRECISION));


More information about the rkward-tracker mailing list