可可运行AppleScript已经包含双引号 [英] Cocoa run AppleScript that already contains double quotes
问题描述
我有一个Cocoa应用程序需要管理员权限执行一个cmd,
但在某些极端的情况下一样包含双引号的文件名,这code不起作用。
的NSString *文件名= @〜/文档/我的\\文件/;
* NSString的CMD = [的NSString stringWithFormat:@CHOWN -R'%@'%@'; NSUserName(),文件名];
* NSString的cmd_execute = [的NSString stringWithFormat:@做shell脚本
\\%@ \\以管理员权限,cmd_execute]
//这行是问题,我们的%@包含双引号,因此可可
//不能跨preT正常。
下面是正确的方式将参数传递到使用NSAppleScript一个AppleScript处理程序:
//加载/编译的AppleScript
NSAppleScript * SCPT = [[NSAppleScript页头] initWithSource:
@关于joinText(A,B)\\ n
@返回和b \\ N
@结束AddTo就];* NSString的ARG1 = @你好;
* NSString的ARG2 = @的世界!//包位置参数
NSAppleEventDescriptor * PARAMS = [NSAppleEventDescriptor listDescriptor]
[PARAMS insertDescriptor:[NSAppleEventDescriptor descriptorWithString:ARG1] atIndex:1];
[PARAMS insertDescriptor:[NSAppleEventDescriptor descriptorWithString:ARG2] atIndex:2];//建立苹果事件调用脚本用户定义的处理程序
NSAppleEventDescriptor * eventDesc = [NSAppleEventDescriptor appleEventWithEventClass:ASCR
事件ID:'PSBR
targetDescriptor:[NSAppleEventDescriptor nullDescriptor]
returnID:0
TRANSACTIONID:0];
[eventDesc setDescriptor:PARAMS forKeyword:'----'];
[eventDesc setDescriptor:[NSAppleEventDescriptor descriptorWithString:@joinText] forKeyword:SNAM']; //调用处理程序
*的NSDictionary = errorInfo中零;
NSAppleEventDescriptor * resultDesc = [SCPT executeAppleEvent:eventDesc错误:&放大器; errorInfo中]。
如果(resultDesc)
的NSLog(@结果:%@ \\ n,[resultDesc stringValue的]);
其他
的NSLog(@错误:%@ \\ n,errorInfo中);
这避免了需要munge和编译AS动态脚本 - 这,你原来ObjC code演示,是引入错误和安全漏洞到你的程序,由于消毒不够丰富的机会。
...
这里是组装在AppleScript的shell脚本的字符串的正确方法:
做shell脚本(CHOWN -R&放大器;用户名和放大器引号形式;&安培;文件路径的引号形式)
的AppleScript的做shell脚本
命令不提供传递参数的安全机制(它在很多其他方面太缺乏),但作为字符串有一个引号形式
属性引用和转义版本的文字适合串联成一个shell脚本字符串。
...
当然,通过调用到壳做shell脚本
AppleScript的只是运行搭配chmod
与升级priveleges不是小本身哈克,虽然这主要是苹果的错不提供的简单的这样做官方的API(例如,通过增加一个选择用管理员权限运行来 NSUserScriptTask
)。
苹果确实提供了示例项目, SMJobBless 的节目如何添加和使用运行服务管理框架和特权的launchd进程。但它是一个十分复杂的解决方案,有很多人会(有意或无意),偷工减料,或做错误的事情完全是,这相当击败提供放在第一位做事的安全方式的地步。但是,你需要采取与苹果公司。
I have a Cocoa application that need admin permission to execute a cmd, but in some extreme case like filename containing double quote, this code does not work.
NSString *fileName = @"~/Documents/My\" File/";
NSString *cmd = [NSString stringWithFormat:@"chown -R '%@' '%@';NSUserName(), fileName];
NSString *cmd_execute = [NSString stringWithFormat:@"do shell script
\"%@\" with administrator privileges",cmd_execute];
//This line is the problem, our %@ contains double quote, so cocoa
//cannot interpret correctly.
Here is the correct way to pass arguments into an AppleScript handler using NSAppleScript:
// load/compile AppleScript
NSAppleScript *scpt = [[NSAppleScript alloc] initWithSource:
@"on joinText(a, b)\n"
@" return a & b\n"
@"end addTo"];
NSString *arg1 = @"Hello ";
NSString *arg2 = @"World!";
// pack positional parameters
NSAppleEventDescriptor *params = [NSAppleEventDescriptor listDescriptor];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg1] atIndex: 1];
[params insertDescriptor: [NSAppleEventDescriptor descriptorWithString: arg2] atIndex: 2];
// build Apple event to invoke user-defined handler in script
NSAppleEventDescriptor *eventDesc = [NSAppleEventDescriptor appleEventWithEventClass: 'ascr'
eventID: 'psbr'
targetDescriptor: [NSAppleEventDescriptor nullDescriptor]
returnID: 0
transactionID: 0];
[eventDesc setDescriptor: params forKeyword: '----'];
[eventDesc setDescriptor: [NSAppleEventDescriptor descriptorWithString: @"joinText"] forKeyword: 'snam'];
// invoke handler
NSDictionary *errorInfo = nil;
NSAppleEventDescriptor *resultDesc = [scpt executeAppleEvent: eventDesc error: &errorInfo];
if (resultDesc)
NSLog(@"Result: %@\n", [resultDesc stringValue]);
else
NSLog(@"Error: %@\n", errorInfo);
This avoids the need to munge and compile AS scripts on the fly - which, as your original ObjC code demonstrates, is a rich opportunity to introduce bugs and security holes into your program due to inadequate sanitization.
...
And here is the correct way to assemble shell script strings in AppleScript:
do shell script ("chown -R " & quoted form of username & " " & quoted form of filepath)
AppleScript's do shell script
command doesn't provide a safe mechanism for passing arguments (it's deficient in a lot of other ways too), but AS strings have a quoted form
property that at least returns a quoted and escaped version of the text suitable for concatenating into a shell script string.
...
Of course, calling into shell via do shell script
AppleScript just to run chmod
with escalated priveleges is not a little hacky in itself, though this is mostly Apple's fault for not providing a simple official API for doing so (e.g. by adding a 'run with admin privileges' option to NSUserScriptTask
).
Apple do provide a sample project, SMJobBless that shows how to add and run privileged processes using the Service Management framework and launchd. But it's a sufficiently complex solution that a lot of folks will (knowingly or unknowingly) cut corners or do the wrong thing entirely, which rather defeats the point of providing a secure way of doing things in the first place. But you'll need to take that up with Apple.
这篇关于可可运行AppleScript已经包含双引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!