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

Code before:
      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;

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

    return await updateOneObjectMetadataItem({
      idToUpdate: objectMetadataItem.id,

Review comment (bug):
The previousNamePlural value is used directly in a RegExp constructor without escaping special regex characters. If an object name contains special regex characters (like parentheses, brackets, dots, or hyphens), this could lead to incorrect replacement behavior or runtime errors. Consider escaping this value using a regex escape function before using it in the RegExp constructor.

Code after:
      });
    } 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,
      });
    }

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

  return (