可可运行AppleScript已经包含双引号 [英] Cocoa run AppleScript that already contains double quotes

查看:379
本文介绍了可可运行AppleScript已经包含双引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆