Repository: twentyhq/twenty
File: packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsUpdateDataModelObjectAboutForm.tsx (TypeScript)

Code before:
        icon: icon ?? undefined,
        isLabelSyncedWithName: formValues.isLabelSyncedWithName,
        labelPlural: updatedObject?.data?.updateOneObject.labelPlural,
        labelSingular: updatedObject?.data?.updateOneObject.labelSingular,
        namePlural: updatedObject?.data?.updateOneObject.namePlural,
        nameSingular: updatedObject?.data?.updateOneObject.nameSingular,
      });
    } else {
      formConfig.reset(undefined, { keepValues: true });
    }

    navigate(SettingsPath.ObjectDetail, {
      objectNamePlural: objectNamePluralForRedirection,
    });

    const previousNamePlural = objectMetadataItem.namePlural;
    const updatedNamePlural = updatedObject?.data?.updateOneObject.namePlural;

    if (!updatedNamePlural) return;

    setNavigationMemorizedUrl((prev) => {
      if (!prev) return prev;

      const objectRouteRegex = new RegExp(
        `^/objects/${previousNamePlural}(/|\\?|$)`,
      );

      if (!objectRouteRegex.test(prev)) {
        return prev;
      }

      return prev.replace(
        new RegExp(`^/objects/${previousNamePlural}`),
        `/objects/${updatedNamePlural}`,
      );
    });
  };

  const updateObjectMetadata = async (
    formValues: SettingsDataModelObjectAboutFormValues,
  ) => {
    const updatePayload = { ...formValues };

    if (!objectMetadataItem.isCustom) {
      const {
        nameSingular: _nameSingular,
        namePlural: _namePlural,
        isLabelSyncedWithName: _isLabelSyncedWithName,
        ...payloadWithoutNames
      } = updatePayload;


Review comment (bug):
The previousNamePlural and updatedNamePlural values are used directly in RegExp constructors without escaping special regex characters. If an object name contains special regex characters (like parentheses, brackets, dots, or hyphens), this could lead to incorrect matching or runtime errors. Consider escaping these values using a regex escape function before using them in the RegExp constructor.

Code after:
      formConfig.reset({
        description,
        icon: icon ?? undefined,
        isLabelSyncedWithName: formValues.isLabelSyncedWithName,
        labelPlural: updatedObject?.data?.updateOneObject.labelPlural,
        labelSingular: updatedObject?.data?.updateOneObject.labelSingular,
        namePlural: updatedObject?.data?.updateOneObject.namePlural,
        nameSingular: updatedObject?.data?.updateOneObject.nameSingular,
      });
    } else {
      formConfig.reset(undefined, { keepValues: true });
    }

    navigate(SettingsPath.ObjectDetail, {
      objectNamePlural: objectNamePluralForRedirection,
    });

    const updatedObjectNamePlural =
      updatedObject?.data?.updateOneObject.namePlural;

    if (!isDefined(updatedObjectNamePlural)) {
      return;
    }

    setNavigationMemorizedUrl((previousNavigationMemorizedUrl) =>
      computeUpdatedNavigationMemorizedUrlAfterObjectNamePluralChange(
        previousNavigationMemorizedUrl,
        objectMetadataItem.namePlural,
        updatedObjectNamePlural,
      ),
    );
  };

  const updateObjectMetadata = async (
    formValues: SettingsDataModelObjectAboutFormValues,
  ) => {
    const updatePayload = { ...formValues };

    if (!objectMetadataItem.isCustom) {
      const {
        nameSingular: _nameSingular,
        namePlural: _namePlural,
        isLabelSyncedWithName: _isLabelSyncedWithName,
        ...payloadWithoutNames
      } = updatePayload;

      return await updateOneObjectMetadataItem({
        idToUpdate: objectMetadataItem.id,
        updatePayload: payloadWithoutNames,
      });
    }