Moar property lists: slow-gpus.plist (matching patterns for GPUs where we should default to simple shaders, unimplemented); shipdata-overrides.plist (fixes for known, minor, third-party problems; currently suppresses one harmless error from griff_spacebar_subent_template); script-patches.plist, similar auto-patcher for third-party scripts (unimplemented). Also, syntax error reports for legacy scripts now provide a sort of path to the problem, e.g. assassins.0.do.321.do.1.conditions.0, which just happens to provide information needed to write script-patches.plist entries.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@2382 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2009-09-04 19:00:30 +00:00
parent 15dae1b410
commit 238d0feaee
13 changed files with 185 additions and 47 deletions

View File

@ -60,6 +60,8 @@
1A20F7070F36EE0500156DE9 /* OOExcludeObjectEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A20F7050F36EE0500156DE9 /* OOExcludeObjectEnumerator.m */; };
1A21149B0DEA980800444CEB /* oolite-ball-turret.dat in Copy Models */ = {isa = PBXBuildFile; fileRef = 1A21149A0DEA980800444CEB /* oolite-ball-turret.dat */; };
1A21149E0DEA98D100444CEB /* oolite-ball-turret.png in Copy Textures */ = {isa = PBXBuildFile; fileRef = 1A21149D0DEA98D100444CEB /* oolite-ball-turret.png */; };
1A2123271051892500530CDE /* shipdata-overrides.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1A2123261051892500530CDE /* shipdata-overrides.plist */; };
1A2123291051892D00530CDE /* slow-gpus.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1A2123281051892D00530CDE /* slow-gpus.plist */; };
1A2315520B9C778400EF0852 /* solar.png in Copy Images */ = {isa = PBXBuildFile; fileRef = 1A23154E0B9C778400EF0852 /* solar.png */; };
1A2315530B9C778400EF0852 /* splash.png in Resources */ = {isa = PBXBuildFile; fileRef = 1A23154F0B9C778400EF0852 /* splash.png */; };
1A2315540B9C778400EF0852 /* splashback.png in Resources */ = {isa = PBXBuildFile; fileRef = 1A2315500B9C778400EF0852 /* splashback.png */; };
@ -1065,7 +1067,7 @@
083325DC09DDBCDE00F5B8E4 /* OOColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOColor.m; sourceTree = "<group>"; };
083DB4D30A70E51E00B419B2 /* OOBrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOBrain.h; sourceTree = "<group>"; };
083DB4D40A70E51E00B419B2 /* OOBrain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOBrain.m; sourceTree = "<group>"; };
0865432206B8447D000CA0AB /* Oolite.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Oolite.app; sourceTree = BUILT_PRODUCTS_DIR; };
0865432206B8447D000CA0AB /* OoliteDev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OoliteDev.app; sourceTree = BUILT_PRODUCTS_DIR; };
0878FD2F086EF845004CB752 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
1A020E0A0D020AFB00C3F51E /* changedScriptHandlers.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = changedScriptHandlers.plist; sourceTree = "<group>"; };
@ -1101,6 +1103,8 @@
1A20F7050F36EE0500156DE9 /* OOExcludeObjectEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOExcludeObjectEnumerator.m; sourceTree = "<group>"; };
1A21149A0DEA980800444CEB /* oolite-ball-turret.dat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "oolite-ball-turret.dat"; sourceTree = "<group>"; };
1A21149D0DEA98D100444CEB /* oolite-ball-turret.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "oolite-ball-turret.png"; sourceTree = "<group>"; };
1A2123261051892500530CDE /* shipdata-overrides.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "shipdata-overrides.plist"; sourceTree = "<group>"; };
1A2123281051892D00530CDE /* slow-gpus.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "slow-gpus.plist"; sourceTree = "<group>"; };
1A23154E0B9C778400EF0852 /* solar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = solar.png; sourceTree = "<group>"; };
1A23154F0B9C778400EF0852 /* splash.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = splash.png; sourceTree = "<group>"; };
1A2315500B9C778400EF0852 /* splashback.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = splashback.png; sourceTree = "<group>"; };
@ -1778,7 +1782,7 @@
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
0865432206B8447D000CA0AB /* Oolite.app */,
0865432206B8447D000CA0AB /* OoliteDev.app */,
1A71E6F30BCE340C00CD5C13 /* libpng.a */,
);
name = Products;
@ -1854,7 +1858,9 @@
1AC973F90C9847850010C42B /* pirate-victim-roles.plist */,
1A95338A0C02089E004EBB58 /* planetinfo.plist */,
1A2316EB0B9CFAD700EF0852 /* shipdata.plist */,
1A2123261051892500530CDE /* shipdata-overrides.plist */,
1A2316EC0B9CFAD700EF0852 /* shipyard.plist */,
1A2123281051892D00530CDE /* slow-gpus.plist */,
1A2316ED0B9CFAD700EF0852 /* speech_pronunciation_guide.plist */,
1A3591820C1C382700E52220 /* startextures.plist */,
1A3491290BC25EAA00802DA7 /* world-scripts.plist */,
@ -3055,7 +3061,7 @@
name = Oolite;
productInstallPath = "$(HOME)/Applications";
productName = Oolite;
productReference = 0865432206B8447D000CA0AB /* Oolite.app */;
productReference = 0865432206B8447D000CA0AB /* OoliteDev.app */;
productType = "com.apple.product-type.application";
};
1A71E6F20BCE340C00CD5C13 /* libpng-custom */ = {
@ -3150,6 +3156,8 @@
25F3E8B40994FE9B002F25FD /* InfoPlist.strings in Resources */,
1A358CE20C1AB80D00E52220 /* ReadMe.rtfd in Resources */,
1ABFEE2210507987005AA752 /* oolite-nonshared.xcconfig in Resources */,
1A2123271051892500530CDE /* shipdata-overrides.plist in Resources */,
1A2123291051892D00530CDE /* slow-gpus.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,12 @@
(
{
path = ("assassins", 0, "do", 321, "do", 1, "conditions", 0);
match = "shipsFound_number less than 20";
replace = "shipsFound_number lessthan 20";
},
{
path = ("assassins", 0, "do", 322, "do", 1, "conditions", 0);
match = "shipsFound_number less than 20";
replace = "shipsFound_number lessthan 20";
}
)

View File

@ -0,0 +1,9 @@
/* Fixes for known problems in third-party ship data.
*/
{
griff_spacebar_subent_template =
{
is_template = yes;
};
}

View File

@ -0,0 +1,26 @@
/* Recognition patterns for OpenGL renderers known to have low shader
performance, for which simple shader mode should be the default.
*/
(
{
// NVIDIA GeForce FX 5200
vendor =
{
sequences =
(
( "GeForce", "5200" )
);
};
},
{
// Also NVIDIA GeForce FX 5200
vendor =
{
sequences =
(
( "NV34MAP" )
);
};
}
)

View File

@ -88,7 +88,7 @@ static NSString * const kOOLogNoteShowShipyardModel = @"script.debug.note.showSh
{
[self runUnsanitizedScriptActions:[rescuee script]
allowingAIMethods:YES
withContextName:[NSString stringWithFormat:@"character \"%@\" script", [rescuee name]]
withContextName:[NSString stringWithFormat:@"<character \"%@\" script>", [rescuee name]]
forTarget:nil];
}
else if ([rescuee insuranceCredits])

View File

@ -111,7 +111,6 @@ static NSString * const kOOLogSyntaxIncrement = @"script.debug.syntax.increme
static NSString * const kOOLogSyntaxDecrement = @"script.debug.syntax.decrement";
static NSString * const kOOLogSyntaxAdd = @"script.debug.syntax.add";
static NSString * const kOOLogSyntaxSubtract = @"script.debug.syntax.subtract";
static NSString * const kOOLogInvalidComparison = @"script.debug.syntax.badComparison";
static NSString * const kOOLogRemoveAllCargoNotDocked = @"script.error.removeAllCargo.notDocked";
@ -1832,7 +1831,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
if ([tokens count] < 2)
{
OOLog(@"script.debug.syntax.subtract", @"***** SCRIPT ERROR: in %@, CANNOT SUBTRACT: '%@'", CurrentScriptDesc(), missionVariableString_value);
OOLog(kOOLogSyntaxSubtract, @"***** SCRIPT ERROR: in %@, CANNOT SUBTRACT: '%@'", CurrentScriptDesc(), missionVariableString_value);
return;
}
@ -1857,7 +1856,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
}
else
{
OOLog(kOOLogSyntaxAdd, @"***** SCRIPT ERROR: in %@, CANNOT ADD: '%@' -- IDENTIFIER '%@' DOES NOT BEGIN WITH 'mission_' or 'local_'", CurrentScriptDesc(), missionVariableString_value);
OOLog(kOOLogSyntaxSubtract, @"***** SCRIPT ERROR: in %@, CANNOT ADD: '%@' -- IDENTIFIER '%@' DOES NOT BEGIN WITH 'mission_' or 'local_'", CurrentScriptDesc(), missionVariableString_value);
}
}

View File

@ -2104,7 +2104,7 @@ static WormholeEntity *whole = nil;
[player setScriptTarget:(ShipEntity*)targEnt];
[player runUnsanitizedScriptActions:[NSArray arrayWithObject:action]
allowingAIMethods:YES
withContextName:[NSString stringWithFormat:@"AI \"%@\" state %@", [[self getAI] name], [[self getAI] state]]
withContextName:[NSString stringWithFormat:@"<AI \"%@\" state %@ - scriptActionOnTarget:>", [[self getAI] name], [[self getAI] state]]
forTarget:targEnt];
[player checkScript]; // react immediately to any changes this makes
[player setScriptTarget:oldTarget];
@ -2124,7 +2124,7 @@ static WormholeEntity *whole = nil;
[player setScriptTarget:(ShipEntity*)targEnt];
[player runUnsanitizedScriptActions:[NSArray arrayWithObject:action]
allowingAIMethods:YES
withContextName:[NSString stringWithFormat:@"AI \"%@\" state %@", [[self getAI] name], [[self getAI] state]]
withContextName:[NSString stringWithFormat:@"<AI \"%@\" state %@ - safeScriptActionOnTarget:>", [[self getAI] name], [[self getAI] state]]
forTarget:targEnt];
[player setScriptTarget:oldTarget];
}

View File

@ -214,7 +214,7 @@ static NSDictionary *sEquipmentTypesByIdentifier = nil;
}
if (conditions != nil)
{
_conditions = OOSanitizeLegacyScriptConditions(conditions, [NSString stringWithFormat:@"equipment type \"%@\"", _name]);
_conditions = OOSanitizeLegacyScriptConditions(conditions, [NSString stringWithFormat:@"<equipment type \"%@\">", _name]);
[_conditions retain];
}
}

View File

@ -834,7 +834,7 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
{
if ([conditions isKindOfClass:[NSArray class]])
{
conditions = OOSanitizeLegacyScriptConditions(conditions, [NSString stringWithFormat:@"shipdata.plist entry \"%@\"", shipKey]);
conditions = OOSanitizeLegacyScriptConditions(conditions, [NSString stringWithFormat:@"<shipdata.plist entry \"%@\">", shipKey]);
}
else
{
@ -854,7 +854,7 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
if (hasShipyard != nil)
{
hasShipyard = OOSanitizeLegacyScriptConditions(hasShipyard, [NSString stringWithFormat:@"shipdata.plist entry \"%@\" hasShipyard conditions", shipKey]);
hasShipyard = OOSanitizeLegacyScriptConditions(hasShipyard, [NSString stringWithFormat:@"<shipdata.plist entry \"%@\" hasShipyard conditions>", shipKey]);
if (hasShipyard != nil)
{
@ -872,7 +872,7 @@ static NSString * const kDefaultDemoShip = @"coriolis-station";
if ([shipyardConditions isKindOfClass:[NSArray class]])
{
shipyardConditions = OOSanitizeLegacyScriptConditions(shipyardConditions, [NSString stringWithFormat:@"shipyard.plist entry \"%@\"", shipKey]);
shipyardConditions = OOSanitizeLegacyScriptConditions(shipyardConditions, [NSString stringWithFormat:@"<shipyard.plist entry \"%@\">", shipKey]);
}
else
{

View File

@ -1006,7 +1006,7 @@ static JSBool ShipRunLegacyScriptActions(JSContext *context, JSObject *this, uin
[player setScriptTarget:thisEnt];
[player runUnsanitizedScriptActions:actions
allowingAIMethods:YES
withContextName:[NSString stringWithFormat:@"ship \"%@\" legacy actions", [thisEnt name]]
withContextName:[NSString stringWithFormat:@"<ship \"%@\" legacy actions>", [thisEnt name]]
forTarget:target];
return YES;

View File

@ -68,8 +68,8 @@ the sanitized form (with rawString values replaced with "..." for simplicity) is
(
true, // This is a conditonal statement
( // conditions
(OP_NUMBER, "...", "galaxy_number", COMPARISON_EQUAL, (false, "4")),
(OP_STRING, "...", "status_string", COMPARISON_EQUAL, (false, "STATUS_EXITING_WITCHSPACE")),
(OP_NUMBER, "...", "galaxy_number", COMPARISON_EQUAL, ((false, "4"))),
(OP_STRING, "...", "status_string", COMPARISON_EQUAL, ((false, "STATUS_EXITING_WITCHSPACE"))),
(OP_MISSION_VAR, "...", "mission_cloak", COMPARISON_UNDEFINED, ())
),
( // do
@ -83,8 +83,8 @@ the sanitized form (with rawString values replaced with "..." for simplicity) is
(false, "checkForShips:", "asp-cloaked"),
(true,
(
(OP_NUMBER, "...", "shipsFound_number", COMPARISON_EQUAL, (false, "0")),
(OP_MISSION_VAR, "...", "mission_cloakcounter, COMPARISON_GREATERTHAN, (false, "6")),
(OP_NUMBER, "...", "shipsFound_number", COMPARISON_EQUAL, ((false, "0"))),
(OP_MISSION_VAR, "...", "mission_cloakcounter, COMPARISON_GREATERTHAN, ((false, "6"))),
),
(
(false, "addShips:", "asp-cloaked 1"),

View File

@ -31,22 +31,47 @@ MA 02110-1301, USA.
#import "NSDictionaryOOExtensions.h"
static NSArray *SanitizeCondition(NSString *condition, NSString *context);
static NSArray *SanitizeConditionalStatement(NSDictionary *statement, NSString *context, BOOL allowAIMethods);
static NSArray *SanitizeActionStatement(NSString *statement, NSString *context, BOOL allowAIMethods);
static OOOperationType ClassifyLHSConditionSelector(NSString *selectorString, NSString **outSanitizedMethod, NSString *context);
#define OUTPUT_PLIST_PATHS 0 // If nonzero, output is formatted for script-patches.plist.
typedef struct SanStackElement SanStackElement;
struct SanStackElement
{
SanStackElement *back;
NSString *key; // Dictionary key; nil for arrays.
OOUInteger index; // Array index if key is nil.
};
static NSArray *OOSanitizeLegacyScriptInternal(NSArray *script, SanStackElement *stack, BOOL allowAIMethods);
static NSArray *OOSanitizeLegacyScriptConditionsInternal(NSArray *conditions, SanStackElement *stack);
static NSArray *SanitizeCondition(NSString *condition, SanStackElement *stack);
static NSArray *SanitizeConditionalStatement(NSDictionary *statement, SanStackElement *stack, BOOL allowAIMethods);
static NSArray *SanitizeActionStatement(NSString *statement, SanStackElement *stack, BOOL allowAIMethods);
static OOOperationType ClassifyLHSConditionSelector(NSString *selectorString, NSString **outSanitizedMethod, SanStackElement *stack);
static NSString *SanitizeQueryMethod(NSString *selectorString); // Checks aliases and whitelist, returns nil if whitelist fails.
static NSString *SanitizeActionMethod(NSString *selectorString, BOOL allowAIMethods); // Checks aliases and whitelist, returns nil if whitelist fails.
static NSArray *AlwaysFalseConditions(void);
static BOOL IsAlwaysFalseConditions(NSArray *conditions);
static NSString *StringFromStack(SanStackElement *topOfStack);
NSArray *OOSanitizeLegacyScript(NSArray *script, NSString *context, BOOL allowAIMethods)
{
SanStackElement stackRoot = { NULL, context, 0 };
return OOSanitizeLegacyScriptInternal(script, &stackRoot, allowAIMethods);
}
static NSArray *OOSanitizeLegacyScriptInternal(NSArray *script, SanStackElement *stack, BOOL allowAIMethods)
{
NSAutoreleasePool *pool = nil;
NSMutableArray *result = nil;
NSEnumerator *statementEnum = nil;
id statement = nil;
OOUInteger index = 0;
pool = [[NSAutoreleasePool alloc] init];
@ -54,17 +79,22 @@ NSArray *OOSanitizeLegacyScript(NSArray *script, NSString *context, BOOL allowAI
for (statementEnum = [script objectEnumerator]; (statement = [statementEnum nextObject]); )
{
SanStackElement subStack =
{
stack, nil, index++
};
if ([statement isKindOfClass:[NSDictionary class]])
{
statement = SanitizeConditionalStatement(statement, context, allowAIMethods);
statement = SanitizeConditionalStatement(statement, &subStack, allowAIMethods);
}
else if ([statement isKindOfClass:[NSString class]])
{
statement = SanitizeActionStatement(statement, context, allowAIMethods);
statement = SanitizeActionStatement(statement, &subStack, allowAIMethods);
}
else
{
OOLog(@"script.syntax.statement.invalidType", @"***** SCRIPT ERROR: in %@, statement is of invalid type - expected string or dictionary, got %@.", context, [statement class]);
OOLog(@"script.syntax.statement.invalidType", @"***** SCRIPT ERROR: in %@, statement is of invalid type - expected string or dictionary, got %@.", StringFromStack(stack), [statement class]);
statement = nil;
}
@ -82,28 +112,41 @@ NSArray *OOSanitizeLegacyScript(NSArray *script, NSString *context, BOOL allowAI
NSArray *OOSanitizeLegacyScriptConditions(NSArray *conditions, NSString *context)
{
if (context == nil) context = @"<anonymous conditions>";
SanStackElement stackRoot = { NULL, context, 0 };
return OOSanitizeLegacyScriptConditionsInternal(conditions, &stackRoot);
}
static NSArray *OOSanitizeLegacyScriptConditionsInternal(NSArray *conditions, SanStackElement *stack)
{
NSEnumerator *conditionEnum = nil;
NSString *condition = nil;
NSMutableArray *result = nil;
NSArray *tokens = nil;
BOOL OK = YES;
OOUInteger index = 0;
if (OOLegacyConditionsAreSanitized(conditions) || conditions == nil) return conditions;
if (context == nil) context = @"<anonymous conditions>";
result = [NSMutableArray arrayWithCapacity:[conditions count]];
for (conditionEnum = [conditions objectEnumerator]; (condition = [conditionEnum nextObject]); )
{
SanStackElement subStack =
{
stack, nil, index++
};
if (![condition isKindOfClass:[NSString class]])
{
OOLog(@"script.syntax.condition.notString", @"***** SCRIPT ERROR: in %@, bad condition - expected string, got %@; ignoring.", context, [condition class]);
OOLog(@"script.syntax.condition.notString", @"***** SCRIPT ERROR: in %@, bad condition - expected string, got %@; ignoring.", StringFromStack(stack), [condition class]);
OK = NO;
break;
}
tokens = SanitizeCondition(condition, context);
tokens = SanitizeCondition(condition, &subStack);
if (tokens != nil)
{
[result addObject:tokens];
@ -127,7 +170,7 @@ BOOL OOLegacyConditionsAreSanitized(NSArray *conditions)
}
static NSArray *SanitizeCondition(NSString *condition, NSString *context)
static NSArray *SanitizeCondition(NSString *condition, SanStackElement *stack)
{
NSArray *tokens = nil;
OOUInteger i, tokenCount;
@ -147,16 +190,16 @@ static NSArray *SanitizeCondition(NSString *condition, NSString *context)
if (tokenCount < 1)
{
OOLog(@"script.debug.syntax.scriptCondition.noneSpecified", @"***** SCRIPT ERROR: in %@, empty script condition.", context);
OOLog(@"script.debug.syntax.scriptCondition.noneSpecified", @"***** SCRIPT ERROR: in %@, empty script condition.", StringFromStack(stack));
return NO;
}
// Parse left-hand side.
selectorString = [tokens stringAtIndex:0];
opType = ClassifyLHSConditionSelector(selectorString, &sanitizedSelectorString, context);
opType = ClassifyLHSConditionSelector(selectorString, &sanitizedSelectorString, stack);
if (opType >= OP_INVALID)
{
OOLog(@"script.unpermittedMethod", @"***** SCRIPT ERROR: in %@, method '%@' not allowed.", context, selectorString);
OOLog(@"script.unpermittedMethod", @"***** SCRIPT ERROR: in %@, method '%@' not allowed.", StringFromStack(stack), selectorString);
return NO;
}
@ -173,7 +216,7 @@ static NSArray *SanitizeCondition(NSString *condition, NSString *context)
else if ([comparatorString isEqualToString:@"undefined"]) comparatorValue = COMPARISON_UNDEFINED;
else
{
OOLog(@"script.debug.syntax.badComparison", @"***** SCRIPT ERROR: in %@, unknown comparison operator '%@', will return NO.", context, comparatorString);
OOLog(@"script.debug.syntax.badComparison", @"***** SCRIPT ERROR: in %@, unknown comparison operator '%@', will return NO.", StringFromStack(stack), comparatorString);
return NO;
}
}
@ -184,14 +227,14 @@ static NSArray *SanitizeCondition(NSString *condition, NSString *context)
Returning NO here causes AlwaysFalseConditions() to be used, which
has the same effect.
*/
OOLog(@"script.debug.syntax.noOperator", @"----- WARNING: SCRIPT in %@ -- No operator in expression '%@', will always evaluate as false.", context, condition);
OOLog(@"script.debug.syntax.noOperator", @"----- WARNING: SCRIPT in %@ -- No operator in expression '%@', will always evaluate as false.", StringFromStack(stack), condition);
return NO;
}
// Check for invalid opType/comparator combinations.
if (opType == OP_NUMBER && comparatorValue == COMPARISON_UNDEFINED)
{
OOLog(@"script.debug.syntax.invalidOperator", @"***** SCRIPT ERROR: in %@, comparison operator '%@' is not valid for %@.", context, @"undefined", @"numbers");
OOLog(@"script.debug.syntax.invalidOperator", @"***** SCRIPT ERROR: in %@, comparison operator '%@' is not valid for %@.", StringFromStack(stack), @"undefined", @"numbers");
return NO;
}
else if (opType == OP_BOOL)
@ -204,7 +247,7 @@ static NSArray *SanitizeCondition(NSString *condition, NSString *context)
break;
default:
OOLog(@"script.debug.syntax.invalidOperator", @"***** SCRIPT ERROR: in %@, comparison operator '%@' is not valid for %@.", context, OOComparisonTypeToString(comparatorValue), @"booleans");
OOLog(@"script.debug.syntax.invalidOperator", @"***** SCRIPT ERROR: in %@, comparison operator '%@' is not valid for %@.", StringFromStack(stack), OOComparisonTypeToString(comparatorValue), @"booleans");
return NO;
}
@ -266,7 +309,7 @@ static NSArray *SanitizeCondition(NSString *condition, NSString *context)
}
static NSArray *SanitizeConditionalStatement(NSDictionary *statement, NSString *context, BOOL allowAIMethods)
static NSArray *SanitizeConditionalStatement(NSDictionary *statement, SanStackElement *stack, BOOL allowAIMethods)
{
NSArray *conditions = nil;
NSArray *doActions = nil;
@ -275,12 +318,13 @@ static NSArray *SanitizeConditionalStatement(NSDictionary *statement, NSString *
conditions = [statement arrayForKey:@"conditions"];
if (conditions == nil)
{
OOLog(@"script.syntax.noConditions", @"***** SCRIPT ERROR: in %@, conditions array contains no \"conditions\" entry, ignoring.", context);
OOLog(@"script.syntax.noConditions", @"***** SCRIPT ERROR: in %@, conditions array contains no \"conditions\" entry, ignoring.", StringFromStack(stack));
return nil;
}
// Sanitize conditions.
conditions = OOSanitizeLegacyScriptConditions(conditions, context);
SanStackElement subStack = { stack, @"conditions", 0 };
conditions = OOSanitizeLegacyScriptConditionsInternal(conditions, &subStack);
if (conditions == nil)
{
return nil;
@ -288,10 +332,18 @@ static NSArray *SanitizeConditionalStatement(NSDictionary *statement, NSString *
// Sanitize do and else.
if (!IsAlwaysFalseConditions(conditions)) doActions = [statement arrayForKey:@"do"];
if (doActions != nil) doActions = OOSanitizeLegacyScript(doActions, context, allowAIMethods);
if (doActions != nil)
{
subStack.key = @"do";
doActions = OOSanitizeLegacyScriptInternal(doActions, &subStack, allowAIMethods);
}
elseActions = [statement arrayForKey:@"else"];
if (elseActions != nil) elseActions = OOSanitizeLegacyScript(elseActions, context, allowAIMethods);
if (elseActions != nil)
{
subStack.key = @"else";
elseActions = OOSanitizeLegacyScriptInternal(elseActions, &subStack, allowAIMethods);
}
// If neither does anything, the statment has no effect.
if ([doActions count] == 0 && [elseActions count] == 0)
@ -306,7 +358,7 @@ static NSArray *SanitizeConditionalStatement(NSDictionary *statement, NSString *
}
static NSArray *SanitizeActionStatement(NSString *statement, NSString *context, BOOL allowAIMethods)
static NSArray *SanitizeActionStatement(NSString *statement, SanStackElement *stack, BOOL allowAIMethods)
{
NSMutableArray *tokens = nil;
OOUInteger tokenCount;
@ -322,7 +374,7 @@ static NSArray *SanitizeActionStatement(NSString *statement, NSString *context,
selectorString = SanitizeActionMethod(rawSelectorString, allowAIMethods);
if (selectorString == nil)
{
OOLog(@"script.unpermittedMethod", @"***** SCRIPT ERROR: in %@, method '%@' not allowed. In a future version of Oolite, this method will be removed from the handler. If you believe the handler should allow this method, please report it to bugs@oolite.org.", context, rawSelectorString);
OOLog(@"script.unpermittedMethod", @"***** SCRIPT ERROR: in %@, method '%@' not allowed. In a future version of Oolite, this method will be removed from the handler. If you believe the handler should allow this method, please report it to bugs@oolite.org.", StringFromStack(stack), rawSelectorString);
// return nil;
selectorString = rawSelectorString;
@ -351,7 +403,7 @@ static NSArray *SanitizeActionStatement(NSString *statement, NSString *context,
}
static OOOperationType ClassifyLHSConditionSelector(NSString *selectorString, NSString **outSanitizedSelector, NSString *context)
static OOOperationType ClassifyLHSConditionSelector(NSString *selectorString, NSString **outSanitizedSelector, SanStackElement *stack)
{
assert(outSanitizedSelector != NULL);
@ -365,7 +417,7 @@ static OOOperationType ClassifyLHSConditionSelector(NSString *selectorString, NS
*outSanitizedSelector = SanitizeQueryMethod(selectorString);
if (*outSanitizedSelector == nil)
{
OOLog(@"script.unpermittedMethod", @"***** SCRIPT ERROR: in %@, method '%@' not allowed. In a future version of Oolite, this method will be removed from the handler. If you believe the handler should allow this method, please report it to bugs@oolite.org.", context, selectorString);
OOLog(@"script.unpermittedMethod", @"***** SCRIPT ERROR: in %@, method '%@' not allowed. In a future version of Oolite, this method will be removed from the handler. If you believe the handler should allow this method, please report it to bugs@oolite.org.", StringFromStack(stack), selectorString);
// return OP_INVALID;
*outSanitizedSelector = selectorString;
@ -469,3 +521,35 @@ static BOOL IsAlwaysFalseConditions(NSArray *conditions)
{
return [[conditions arrayAtIndex:0] unsignedIntAtIndex:0] == OP_FALSE;
}
static NSMutableString *StringFromStackInternal(SanStackElement *topOfStack)
{
if (topOfStack == NULL) return nil;
NSMutableString *base = StringFromStackInternal(topOfStack->back);
if (base == nil) base = [NSMutableString string];
NSString *string = topOfStack->key;
if (string == nil) string = [NSString stringWithFormat:@"%lu", (unsigned long)topOfStack->index];
#if OUTPUT_PLIST_PATHS
else string = [NSString stringWithFormat:@"\"%@\"", string];
if ([base length] > 0) [base appendString:@", "];
#else
if ([base length] > 0) [base appendString:@"."];
#endif
[base appendString:string];
return base;
}
static NSString *StringFromStack(SanStackElement *topOfStack)
{
#if OUTPUT_PLIST_PATHS
return [NSString stringWithFormat:@"(%@)", StringFromStackInternal(topOfStack)];
#else
return StringFromStackInternal(topOfStack);
#endif
}

View File

@ -679,7 +679,7 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void * context);
{
[player runUnsanitizedScriptActions:script_actions
allowingAIMethods:NO
withContextName:@"witchspace script_actions"
withContextName:@"<witchspace script_actions>"
forTarget:nil];
}
@ -1035,7 +1035,7 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void * context);
{
[[PlayerEntity sharedPlayer] runUnsanitizedScriptActions:script_actions
allowingAIMethods:NO
withContextName:@"system script_actions"
withContextName:@"<system script_actions>"
forTarget:nil];
}
}