指定のテキストをAppleScriptとみなして構文確認して、指定の構文要素が入っていないかチェックするAppleScriptです。
AppleScriptにeval関数はないので、文字列として与えたAppleScriptをその場で実行する「run script」コマンドをevalがわりに使っています。
文字列をそのままrun scriptするのは(一応いろいろ保護機能はあるものの)、セキュリティ的にリスクの高い操作になってしまいます。
▲こんなのがrun scriptコマンドで実行されてしまったらと思うとゾッとします。ためしに実行してみたら、実行権限がないので実行できないエラーになりました
そこで、文字列をいったんAppleScriptとして評価(構文確認)し、コマンドなどの危険と思われる構文要素が入っていないかどうかチェックする処理を書いて使っています。
これら、「コマンド」および「追加コマンド」といった構文要素が入っていたらtrueを返します。
本Scriptをライブラリ化して組み込むことで、少ない記述量で対象の文字列をそのままrun scriptしてよいかどうか判定できるようにしています。
–> Download checkDanger(with Library in its bundle)
▲実際にテキストをAppleScriptとして評価して構文要素を検出し、このようにコマンド部分(AppleScriptのdo shell scriptコマンド)が入っていることを検知できる
AppleScript名:指定のAppleScriptテキストを構文確認して指定の構文要素が入っていないかチェック.scptd |
— – Created by: Takaaki Naganoya – Created on: 2019/07/31 — – Copyright © 2019 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions use framework "AppKit" use framework "OSAKit" use attrLib : script "asAttrRecLib" property NSArray : a reference to current application’s NSArray property OSANull : a reference to current application’s OSANull property NSString : a reference to current application’s NSString property OSAScript : a reference to current application’s OSAScript property NSPredicate : a reference to current application’s NSPredicate property NSDictionary : a reference to current application’s NSDictionary property NSUnarchiver : a reference to current application’s NSUnarchiver property OSALanguage : a reference to current application’s OSALanguage property NSCountedSet : a reference to current application’s NSCountedSet property NSMutableArray : a reference to current application’s NSMutableArray property NSMutableDictionary : a reference to current application’s NSMutableDictionary property OSALanguageInstance : a reference to current application’s OSALanguageInstance script spd property fArray : {} property outList : {} property resStr : {} end script on run set theSource to "do shell script \"rm -f *.*\"" set aRes to chkTargLexicalElementsFromCompiledScriptAttribute(theSource, {9, 14}) of me –{Command, External Command} –> true : 指定の構文要素が入っていた set theSource to "{{aName:\"piyoko\", aVal:100}, {aName:\"piyomaru\", aVal:80}, {aName:\"piyoo\", aVal:10}, {aName:\"Gundamo\", aVal:10}}" set bRes to chkTargLexicalElementsFromCompiledScriptAttribute(theSource, {9, 14}) of me –{Command, External Command} –> false : 指定の構文要素は入っていなかった end run –AppleScriptのソーステキストをコンパイルして、指定の構文要素が含まれているかチェックする on chkTargLexicalElementsFromCompiledScriptAttribute(theSource as string, targLexicalElements as list) –AppleScriptの構文色分け情報を取得 set ccRes to getAppleScriptSourceColors() of me set cRes to chkASLexicalFormatColorConfliction(ccRes) of me –構文色分けの重複色チェック if cRes = false then error "There is some duplicate(s) color among AppleScript’s lexical color settings" –検索用の色情報を作成 set colTargList to {} repeat with i in targLexicalElements set commentCol to contents of item i of ccRes –Variable and Sub-routine name set searchVal to (redValue of commentCol as string) & " " & (greenValue of commentCol as string) & " " & (blueValue of commentCol as string) –for filtering set the end of colTargList to searchVal end repeat –与えられたテキストをAppleScriptとして評価し構文色分け情報をもとにStyle Runs的なDictionary化して返す set aRitch to compileASSourcetextAndReturnStyledText(theSource) of me –書式付きテキストからstyle runs的な書式リストを作成 set anAttrList to getAttributeRunsFromAttrString(aRitch) of attrLib set bList to filterRecListByLabelAndSublist(anAttrList, "colorStr IN %@", colTargList) of me return not (bList as list = {}) as boolean end chkTargLexicalElementsFromCompiledScriptAttribute on retDelimedText(aList, aDelim) set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retDelimedText ——- –AppleScriptの構文色分けのカラー値をRGBで取得する on getAppleScriptSourceColors() — get the plist info as a dictionary set thePath to NSString’s stringWithString:"~/Library/Preferences/com.apple.applescript.plist" set thePath to thePath’s stringByExpandingTildeInPath() set theInfo to NSDictionary’s dictionaryWithContentsOfFile:thePath — extract relevant part and loop through set theArray to (theInfo’s valueForKey:"AppleScriptSourceAttributes") as list set colList to {} repeat with i from 1 to count of theArray set anEntry to item i of theArray set colorData to NSColor of anEntry set theColor to (NSUnarchiver’s unarchiveObjectWithData:colorData) set {rVal, gVal, bVal} to retColListFromNSColor(theColor, 255) of me set fontData to NSFont of anEntry set theFont to (NSUnarchiver’s unarchiveObjectWithData:fontData) set aFontName to theFont’s displayName() as text set aFontSize to theFont’s pointSize() set aColRec to {redValue:rVal, greenValue:gVal, blueValue:bVal, fontName:aFontName, fontSize:aFontSize} set the end of colList to aColRec end repeat return colList end getAppleScriptSourceColors –AppleScriptの構文色分けのカラー値をRGBで取得する on getAppleScriptSourceNSColorsDict() — get the plist info as a dictionary set thePath to NSString’s stringWithString:"~/Library/Preferences/com.apple.applescript.plist" set thePath to thePath’s stringByExpandingTildeInPath() set theInfo to NSDictionary’s dictionaryWithContentsOfFile:thePath — extract relevant part and loop through set theArray to (theInfo’s valueForKey:"AppleScriptSourceAttributes") as list set aDict to NSMutableDictionary’s alloc()’s init() repeat with i from 1 to count of theArray set anEntry to item i of theArray set colorData to NSColor of anEntry set theColor to (NSUnarchiver’s unarchiveObjectWithData:colorData) set {rVal, gVal, bVal} to retColListFromNSColor(theColor, 255) of me set fontData to NSFont of anEntry set theFont to (NSUnarchiver’s unarchiveObjectWithData:fontData) set aFontName to theFont’s displayName() as text set aFontSize to theFont’s pointSize() set colIndStr to (rVal as string) & " " & (gVal as string) & " " & (bVal as string) set tmpColDat to {numList:{rVal, gVal, bVal}, strInd:colIndStr} –(aDict’s addObject:tmpColDat forKey:theColor) (aDict’s addObject:{rVal, gVal, bVal} forKey:theColor) end repeat return aDict end getAppleScriptSourceNSColorsDict –NSColorからRGBの値を取り出す on retColListFromNSColor(aCol, aMAX as integer) set aSpace to (aCol’s colorSpaceName()) as string –set aSpace to (aCol’s type()) as integer if aSpace is in {"NSDeviceRGBColorSpace", "NSCalibratedRGBColorSpace"} then copy aCol to cCol else –RGB以外の色空間の色は、RGBに変換 –CMYKとグレースケールは同一メソッドでRGBに変換できることを確認済み set cCol to aCol’s colorUsingColorSpaceName:"NSCalibratedRGBColorSpace" if cCol = missing value then error "Color Space Conversion Error (" & aSpace & " to NSCalibratedRGBColorSpace)" end if set aRed to round ((cCol’s redComponent()) * aMAX) rounding as taught in school set aGreen to round ((cCol’s greenComponent()) * aMAX) rounding as taught in school set aBlue to round ((cCol’s blueComponent()) * aMAX) rounding as taught in school if aRed > aMAX then set aRed to aMAX if aGreen > aMAX then set aGreen to aMAX if aBlue > aMAX then set aBlue to aMAX return {aRed, aGreen, aBlue} as list end retColListFromNSColor –AS書式で配色に重複がないかどうかチェック on chkASLexicalFormatColorConfliction(aList) set anArray to current application’s NSArray’s arrayWithArray:aList set bList to (anArray’s valueForKeyPath:"redValue.stringValue") as list set cList to (anArray’s valueForKeyPath:"greenValue.stringValue") as list set dList to (anArray’s valueForKeyPath:"blueValue.stringValue") as list set colStrList to {} repeat with i from 1 to (length of bList) set bItem to contents of item i of bList set cItem to contents of item i of cList set dItem to contents of item i of dList set the end of colStrList to bItem & " " & cItem & " " & dItem end repeat set aRes to returnDuplicatesOnly(colStrList) of me if aRes is equal to {} then return true –重複が存在しなかった場合 else return false –重複があった場合 end if end chkASLexicalFormatColorConfliction on returnDuplicatesOnly(aList as list) set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList set bList to (aSet’s allObjects()) as list set dupList to {} repeat with i in bList set aRes to (aSet’s countForObject:i) if aRes > 1 then set the end of dupList to (contents of i) end if end repeat return dupList end returnDuplicatesOnly –テキスト形式のAppleScriptをコンパイルして書式付きテキスト(NSAttributedString)を返す on compileASSourcetextAndReturnStyledText(theSource) — create a new AppleScript instance set anOSALanguageInstance to OSALanguage’s languageForName:"AppleScript" set theScript to OSAScript’s alloc()’s initWithSource:theSource fromURL:(missing value) languageInstance:anOSALanguageInstance usingStorageOptions:(OSANull) set {theResult, theError} to theScript’s compileAndReturnError:(reference) if theResult as boolean is false then — handle error error "Compile Error" else set styledSourceText to theScript’s richTextSource() end if return styledSourceText end compileASSourcetextAndReturnStyledText –文字置換 on repChar(origText as string, targChar as string, repChar as string) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to targChar set tmpList to text items of origText set AppleScript’s text item delimiters to repChar set retText to tmpList as string set AppleScript’s text item delimiters to curDelim return retText end repChar –リストに入れたレコードを、指定の属性ラベルの値で抽出。値が別途指定のリストの中に存在していることが条件 on filterRecListByLabelAndSublist(aRecList as list, aPredicate as string, aSubList as list) set aArray to NSArray’s arrayWithArray:aRecList set aSubArray to NSArray’s arrayWithArray:aSubList –抽出 set aPredicate to NSPredicate’s predicateWithFormat_(aPredicate, aSubArray) set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate return filteredArray as list end filterRecListByLabelAndSublist |