1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-05-21 10:41:29 +00:00

Disallow entry of strings longer than the lengths allowed by the file format.

It is possible to allow longer strings but that will require an extension in the omwaddon format as well as changes to the reader to handle that extension.  Such changes should be a separate MR.

(applied the patch in https://gitlab.com/OpenMW/openmw/-/issues/3066)
This commit is contained in:
cc9cii 2021-08-04 09:06:04 +10:00
parent 31e5fd91d1
commit 8aee84c46e
13 changed files with 82 additions and 7 deletions

View file

@ -1942,6 +1942,7 @@
Bug #2025: Missing mouse-over text for non affordable items Bug #2025: Missing mouse-over text for non affordable items
Bug #2028: [MOD: Tamriel Rebuilt] Crashing when trying to enter interior cell "Ruinous Keep, Great Hall" Bug #2028: [MOD: Tamriel Rebuilt] Crashing when trying to enter interior cell "Ruinous Keep, Great Hall"
Bug #2029: Ienith Brothers Thiev's Guild quest journal entry not adding Bug #2029: Ienith Brothers Thiev's Guild quest journal entry not adding
Bug #3066: Editor doesn't check if IDs and other strings are longer than their hardcoded field length
Feature #471: Editor: Special case implementation for top-level window with single sub-window Feature #471: Editor: Special case implementation for top-level window with single sub-window
Feature #472: Editor: Sub-Window re-use settings Feature #472: Editor: Sub-Window re-use settings
Feature #704: Font colors import from fallback settings Feature #704: Font colors import from fallback settings

View file

@ -104,7 +104,8 @@ bool CSMWorld::ColumnBase::isId (Display display)
bool CSMWorld::ColumnBase::isText (Display display) bool CSMWorld::ColumnBase::isText (Display display)
{ {
return display==Display_String || display==Display_LongString || return display==Display_String || display==Display_LongString ||
display==Display_String32 || display==Display_LongString256; display==Display_String32 || display==Display_String64 ||
display==Display_LongString256;
} }
bool CSMWorld::ColumnBase::isScript (Display display) bool CSMWorld::ColumnBase::isScript (Display display)

View file

@ -135,6 +135,7 @@ namespace CSMWorld
Display_InfoCondVar, Display_InfoCondVar,
Display_InfoCondComp, Display_InfoCondComp,
Display_String32, Display_String32,
Display_String64,
Display_LongString256, Display_LongString256,
Display_BookType, Display_BookType,
Display_BloodType, Display_BloodType,

View file

@ -334,7 +334,8 @@ namespace CSMWorld
template<typename ESXRecordT> template<typename ESXRecordT>
struct NameColumn : public Column<ESXRecordT> struct NameColumn : public Column<ESXRecordT>
{ {
NameColumn() : Column<ESXRecordT> (Columns::ColumnId_Name, ColumnBase::Display_String) {} NameColumn(ColumnBase::Display display = ColumnBase::Display_String)
: Column<ESXRecordT> (Columns::ColumnId_Name, display) {}
QVariant get (const Record<ESXRecordT>& record) const override QVariant get (const Record<ESXRecordT>& record) const override
{ {

View file

@ -130,7 +130,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
mFactions.addColumn (new StringIdColumn<ESM::Faction>); mFactions.addColumn (new StringIdColumn<ESM::Faction>);
mFactions.addColumn (new RecordStateColumn<ESM::Faction>); mFactions.addColumn (new RecordStateColumn<ESM::Faction>);
mFactions.addColumn (new FixedRecordTypeColumn<ESM::Faction> (UniversalId::Type_Faction)); mFactions.addColumn (new FixedRecordTypeColumn<ESM::Faction> (UniversalId::Type_Faction));
mFactions.addColumn (new NameColumn<ESM::Faction>); mFactions.addColumn (new NameColumn<ESM::Faction>(ColumnBase::Display_String32));
mFactions.addColumn (new AttributesColumn<ESM::Faction> (0)); mFactions.addColumn (new AttributesColumn<ESM::Faction> (0));
mFactions.addColumn (new AttributesColumn<ESM::Faction> (1)); mFactions.addColumn (new AttributesColumn<ESM::Faction> (1));
mFactions.addColumn (new HiddenColumn<ESM::Faction>); mFactions.addColumn (new HiddenColumn<ESM::Faction>);
@ -339,7 +339,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat
mCells.addColumn (new StringIdColumn<Cell>); mCells.addColumn (new StringIdColumn<Cell>);
mCells.addColumn (new RecordStateColumn<Cell>); mCells.addColumn (new RecordStateColumn<Cell>);
mCells.addColumn (new FixedRecordTypeColumn<Cell> (UniversalId::Type_Cell)); mCells.addColumn (new FixedRecordTypeColumn<Cell> (UniversalId::Type_Cell));
mCells.addColumn (new NameColumn<Cell>); mCells.addColumn (new NameColumn<Cell>(ColumnBase::Display_String64));
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep)); mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep));
mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater, mCells.addColumn (new FlagColumn<Cell> (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater,
ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh));

View file

@ -59,7 +59,9 @@ CSMWorld::RefIdCollection::RefIdCollection()
NameColumns nameColumns (modelColumns); NameColumns nameColumns (modelColumns);
mColumns.emplace_back(Columns::ColumnId_Name, ColumnBase::Display_String); // Only items that can be placed in a container have the 32 character limit, but enforce
// that for all referenceable types for now.
mColumns.emplace_back(Columns::ColumnId_Name, ColumnBase::Display_String32);
nameColumns.mName = &mColumns.back(); nameColumns.mName = &mColumns.back();
mColumns.emplace_back(Columns::ColumnId_Script, ColumnBase::Display_Script); mColumns.emplace_back(Columns::ColumnId_Script, ColumnBase::Display_Script);
nameColumns.mScript = &mColumns.back(); nameColumns.mScript = &mColumns.back();
@ -231,9 +233,9 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean)); new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String32));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiTargetId, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_AiTargetId, CSMWorld::ColumnBase::Display_String32));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiTargetCell, CSMWorld::ColumnBase::Display_String)); new RefIdColumn (Columns::ColumnId_AiTargetCell, CSMWorld::ColumnBase::Display_String));
mColumns.back().addColumn( mColumns.back().addColumn(
@ -479,6 +481,7 @@ CSMWorld::RefIdCollection::RefIdCollection()
mColumns.emplace_back(Columns::ColumnId_Class, ColumnBase::Display_Class); mColumns.emplace_back(Columns::ColumnId_Class, ColumnBase::Display_Class);
npcColumns.mClass = &mColumns.back(); npcColumns.mClass = &mColumns.back();
// NAME32 enforced in IdCompletionDelegate::createEditor()
mColumns.emplace_back(Columns::ColumnId_Faction, ColumnBase::Display_Faction); mColumns.emplace_back(Columns::ColumnId_Faction, ColumnBase::Display_Faction);
npcColumns.mFaction = &mColumns.back(); npcColumns.mFaction = &mColumns.back();

View file

@ -84,6 +84,13 @@ void CSVWorld::CellCreator::setType (int index)
mYLabel->setVisible (index==1); mYLabel->setVisible (index==1);
mY->setVisible (index==1); mY->setVisible (index==1);
// The cell name is limited to 64 characters. (ESM::Header::GMDT::mCurrentCell)
std::string text = mType->currentText().toStdString();
if (text == "Interior Cell")
GenericCreator::setEditorMaxLength (64);
else
GenericCreator::setEditorMaxLength (32767);
update(); update();
} }

View file

@ -184,6 +184,11 @@ CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undo
connect (&mData, SIGNAL (idListChanged()), this, SLOT (dataIdListChanged())); connect (&mData, SIGNAL (idListChanged()), this, SLOT (dataIdListChanged()));
} }
void CSVWorld::GenericCreator::setEditorMaxLength (int length)
{
mId->setMaxLength (length);
}
void CSVWorld::GenericCreator::setEditLock (bool locked) void CSVWorld::GenericCreator::setEditLock (bool locked)
{ {
mLocked = locked; mLocked = locked;

View file

@ -84,6 +84,8 @@ namespace CSVWorld
std::string getNamespace() const; std::string getNamespace() const;
void setEditorMaxLength(int length);
private: private:
void updateNamespace(); void updateNamespace();

View file

@ -81,6 +81,23 @@ QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent,
CSMWorld::IdCompletionManager &completionManager = getDocument().getIdCompletionManager(); CSMWorld::IdCompletionManager &completionManager = getDocument().getIdCompletionManager();
CSVWidget::DropLineEdit *editor = new CSVWidget::DropLineEdit(display, parent); CSVWidget::DropLineEdit *editor = new CSVWidget::DropLineEdit(display, parent);
editor->setCompleter(completionManager.getCompleter(display).get()); editor->setCompleter(completionManager.getCompleter(display).get());
// The savegame format limits the player faction string to 32 characters.
// The region sound name is limited to 32 characters. (ESM::Region::SoundRef::mSound)
// The script name is limited to 32 characters. (ESM::Script::SCHD::mName)
// The cell name is limited to 64 characters. (ESM::Header::GMDT::mCurrentCell)
if (display == CSMWorld::ColumnBase::Display_Faction ||
display == CSMWorld::ColumnBase::Display_Sound ||
display == CSMWorld::ColumnBase::Display_Script ||
display == CSMWorld::ColumnBase::Display_Referenceable)
{
editor->setMaxLength (32);
}
else if (display == CSMWorld::ColumnBase::Display_Cell)
{
editor->setMaxLength (64);
}
return editor; return editor;
} }

View file

@ -33,6 +33,8 @@ CSVWorld::ReferenceableCreator::ReferenceableCreator (CSMWorld::Data& data, QUnd
} }
insertBeforeButtons (mType, false); insertBeforeButtons (mType, false);
connect (mType, SIGNAL (currentIndexChanged (int)), this, SLOT (setType (int)));
} }
void CSVWorld::ReferenceableCreator::reset() void CSVWorld::ReferenceableCreator::reset()
@ -41,6 +43,30 @@ void CSVWorld::ReferenceableCreator::reset()
GenericCreator::reset(); GenericCreator::reset();
} }
void CSVWorld::ReferenceableCreator::setType (int index)
{
// container items have name limit of 32 characters
std::string text = mType->currentText().toStdString();
if (text == "Potion" ||
text == "Apparatus" ||
text == "Armor" ||
text == "Book" ||
text == "Clothing" ||
text == "Ingredient" ||
text == "ItemLevelledList" ||
text == "Light" ||
text == "Lockpick" ||
text == "Miscellaneous" ||
text == "Probe" ||
text == "Repair" ||
text == "Weapon")
{
GenericCreator::setEditorMaxLength (32);
}
else
GenericCreator::setEditorMaxLength (32767);
}
void CSVWorld::ReferenceableCreator::cloneMode (const std::string& originId, void CSVWorld::ReferenceableCreator::cloneMode (const std::string& originId,
const CSMWorld::UniversalId::Type type) const CSMWorld::UniversalId::Type type)
{ {

View file

@ -29,6 +29,9 @@ namespace CSVWorld
void toggleWidgets(bool active = true) override; void toggleWidgets(bool active = true) override;
private slots:
void setType (int index);
}; };
} }

View file

@ -291,6 +291,14 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO
return widget; return widget;
} }
case CSMWorld::ColumnBase::Display_String64:
{
// For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used
CSVWidget::DropLineEdit *widget = new CSVWidget::DropLineEdit(display, parent);
widget->setMaxLength (64);
return widget;
}
default: default:
return QStyledItemDelegate::createEditor (parent, option, index); return QStyledItemDelegate::createEditor (parent, option, index);