Sketcher: Prevent bad constraint names (#20717)

* Sketcher: Prevent bad constraint names

Ensures the constraint names only contains alphanumericals and
underscores so that they can always be used in expressions.
That way, there cannot be any unicode character or quotes that
would need to be escaped.

Fixes: https://github.com/FreeCAD/FreeCAD/issues/19767

* Add helper function to check constraint names

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Lothaire Sicot <lothaire.sicot@telecom-paris.fr>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Lothaire Sicot
2025-04-21 17:53:37 +02:00
committed by GitHub
parent ef0ca1cff3
commit 1a5bfdb2e9
3 changed files with 33 additions and 8 deletions

View File

@@ -50,6 +50,23 @@ using namespace SketcherGui;
/* TRANSLATOR SketcherGui::EditDatumDialog */
bool SketcherGui::checkConstraintName(const Sketcher::SketchObject* sketch,
std::string constraintName)
{
if (constraintName != Base::Tools::getIdentifier(constraintName)) {
Gui::NotifyUserError(
sketch,
QT_TRANSLATE_NOOP("Notifications", "Value Error"),
QT_TRANSLATE_NOOP("Notifications",
"Invalid constraint name (must only contain alphanumericals and "
"underscores, and must not start with digit)"));
return false;
}
return true;
}
EditDatumDialog::EditDatumDialog(ViewProviderSketch* vp, int ConstrNbr)
: ConstrNbr(ConstrNbr)
, success(false)
@@ -213,15 +230,18 @@ void EditDatumDialog::accepted()
}
}
QString constraintName = ui_ins_datum->name->text().trimmed();
if (constraintName.toStdString() != sketch->Constraints[ConstrNbr]->Name) {
std::string escapedstr =
Base::Tools::escapedUnicodeFromUtf8(constraintName.toUtf8().constData());
escapedstr = Base::Tools::escapeQuotesFromString(escapedstr);
std::string constraintName = ui_ins_datum->name->text().trimmed().toStdString();
std::string currConstraintName = sketch->Constraints[ConstrNbr]->Name;
printf("datum");
if (constraintName != currConstraintName) {
if (!SketcherGui::checkConstraintName(sketch, constraintName)) {
constraintName = currConstraintName;
}
Gui::cmdAppObjectArgs(sketch,
"renameConstraint(%d, u'%s')",
ConstrNbr,
escapedstr.c_str());
constraintName.c_str());
}
Gui::Command::commitCommand();

View File

@@ -38,6 +38,8 @@ namespace SketcherGui
class ViewProviderSketch;
class Ui_InsertDatum;
bool checkConstraintName(const Sketcher::SketchObject* sketch, std::string constraintName);
class EditDatumDialog: public QObject
{
Q_OBJECT

View File

@@ -1223,13 +1223,16 @@ void TaskSketcherConstraints::onListWidgetConstraintsItemChanged(QListWidgetItem
// b) that the text in the widget item, basename, is not ""
// otherwise a checkbox change will trigger a rename on the first execution, bloating the
// constraint icons with the default constraint name "constraint1, constraint2"
printf("task");
if (newName != currConstraintName && !basename.empty()) {
std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(newName.c_str());
if (!SketcherGui::checkConstraintName(sketch, newName)) {
newName = currConstraintName;
}
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Rename sketch constraint"));
try {
Gui::cmdAppObjectArgs(
sketch, "renameConstraint(%d, u'%s')", it->ConstraintNbr, escapedstr.c_str());
sketch, "renameConstraint(%d, u'%s')", it->ConstraintNbr, newName.c_str());
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {