feat(inventory): granular item-level validation and auto-capitalization
Enhances validation to clean corrupted items at load time while preserving valid ones, rather than discarding entire sections. Also auto-capitalizes first letter of items for consistency. New capability - Granular Item Cleaning: 1. **cleanItemString()** (src/utils/security.js): - Parses item string, removes bad items, re-serializes clean ones - Applies ALL parsing rules: markdown, sanitization, length limits - Used at load time to clean persisted data immediately - Returns "None" if no valid items remain 2. **Enhanced validateStoredInventory()**: - Now cleans items within each location - Only removes locations if ALL items are invalid - Example: "Home": "Sword, __proto__, Shield" → "Home": "Sword, Shield" - Example: "Bad": "__proto__, constructor" → location removed 3. **Enhanced validateInventoryStructure()** (src/core/persistence.js): - Cleans onPerson, stored, and assets at load time - Logs exactly what was cleaned for debugging - Auto-saves cleaned data back to storage Auto-Capitalization: - Added to cleanSingleItem() in itemParser.js - Capitalizes first letter of each item after all cleaning - Preserves rest of case: "iPhone" → "iPhone" (not "Iphone") - Examples: "sword" → "Sword", "3x potions" → "3x potions" Behavior examples: Before (threw away entire array): - "Home": "Sword, " + "A".repeat(600) + ", Shield" → Entire location lost After (granular cleaning): - "Home": "Sword, " + "A".repeat(600) + ", Shield" → "Home": "Sword, AAA...(500 chars), Shield" Before (kept corrupted data): - onPerson: "sword, __proto__, shield" → Stored as-is, filtered only at render After (cleaned at load): - onPerson: "Sword, Shield" → Cleaned and saved immediately, capitalized Benefits: - ✓ Preserves valid items when some are corrupted - ✓ Cleans data at source, not just at render - ✓ Detailed logging of what was cleaned - ✓ Consistent capitalization across all items - ✓ Single source of truth for "valid item"
This commit is contained in:
+17
-1
@@ -15,7 +15,7 @@ import {
|
||||
FEATURE_FLAGS
|
||||
} from './state.js';
|
||||
import { migrateInventory } from '../utils/migration.js';
|
||||
import { validateStoredInventory } from '../utils/security.js';
|
||||
import { validateStoredInventory, cleanItemString } from '../utils/security.js';
|
||||
|
||||
const extensionName = 'third-party/rpg-companion-sillytavern';
|
||||
|
||||
@@ -212,6 +212,14 @@ function validateInventoryStructure(inventory, source) {
|
||||
console.warn(`[RPG Companion] Invalid onPerson from ${source}, resetting to "None"`);
|
||||
inventory.onPerson = "None";
|
||||
needsSave = true;
|
||||
} else {
|
||||
// Clean items in onPerson (removes corrupted/dangerous items)
|
||||
const cleanedOnPerson = cleanItemString(inventory.onPerson);
|
||||
if (cleanedOnPerson !== inventory.onPerson) {
|
||||
console.warn(`[RPG Companion] Cleaned corrupted items from onPerson inventory (${source})`);
|
||||
inventory.onPerson = cleanedOnPerson;
|
||||
needsSave = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate stored field (CRITICAL for Bug #3)
|
||||
@@ -234,6 +242,14 @@ function validateInventoryStructure(inventory, source) {
|
||||
console.warn(`[RPG Companion] Invalid assets from ${source}, resetting to "None"`);
|
||||
inventory.assets = "None";
|
||||
needsSave = true;
|
||||
} else {
|
||||
// Clean items in assets (removes corrupted/dangerous items)
|
||||
const cleanedAssets = cleanItemString(inventory.assets);
|
||||
if (cleanedAssets !== inventory.assets) {
|
||||
console.warn(`[RPG Companion] Cleaned corrupted items from assets inventory (${source})`);
|
||||
inventory.assets = cleanedAssets;
|
||||
needsSave = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Persist repairs if needed
|
||||
|
||||
Reference in New Issue
Block a user