2016-01-29 36 views
1

我的劇本目前接受的ActiveSupport日期字符串作爲命令行參數:替代「EVAL」爲的ActiveSupport日期解析

my_script --mindate 1.day 

裏面我的劇本,我使用eval將其保存到我的配置

MyScript.configuration.min_date = eval(min_date_string) 

我知道這是非常狡猾和不安全的,因爲任何東西都可以傳遞給eval,但我的替代品是什麼?

回答

2

你想要時間?我想你可以使用chronic_duration

my_script --mindate "1 day" 
MyScript.configuration.min_date = ChronicDuration.parse(min_date_string) 

但是,由於它是自然語言啓發式,它並不完全明確地定義它將識別哪種字符串。但它會做一些花式的事情,比如「1天和4小時」。

或者你可以爲自變量編寫你自己的非常簡單的解析器/解釋器。只需分割一個空間(用於「1天」類型的輸入)或句點(用於「1.day」)類型的輸入。識別第二個位置(「小時」,「分鐘」,「日」,「月」,「年」)中的幾個單詞,將它們翻譯爲秒,將該數字乘以翻譯後的單詞。大概有十幾行紅寶石。

或者你甚至可以利用ActiveSupport功能來支持諸如「1.day」之類的功能,使其更加簡單。

str = "11 hours" 
    number, unit = str.split(' ') 
    number.to_i.send(unit) 

這將讓命令行用戶發送任何他們想要的數字方法。我不確定這很重要。對於這個問題,我不確定原來的eval是否真的很重要 - 但我同意你的做法是不好的做法。對於這個問題,用戶輸入可能是send,儘管不是那麼糟糕。

或者你可以讓他們發送秒鐘的原始數字並將其自行cal it。

my_script --mindate 86400 

你意識到1.day只是最終被轉換成秒數在一個標準的一天吧?我不確定爲什麼你打電話幾秒鐘「mindate」,但那是你的事!

編輯或者另一種選擇,讓他們做:

my_script --mindays 2 --minhours 4 --minminutes 3 

什麼的。

0

你的腳本如何被調用?這是否總是會被用戶在任何機器上運行的帳戶調用?這是否會以某種方式被Web服務調用,或者以某種方式讓沒有訪問機器的人可以用他們自己的參數遠程調用它?

如果它只會被用戶調用,並且這些用戶已經可以訪問ruby命令或irb,那麼您就不能通過調用eval來完成他們無法完成的任何操作。

如果它被遠程調用,那麼您應該不會使用eval。或者,一個快速和骯髒的解決方案可能會匹配你將用正則表達式評估的模式。像/^[0-9]+(\.[a-z_0-9]+){,2}$/之類的東西可以確保它在評估之前在Fixnum文字的2個方法調用中。

+0

我同意你說這可能不是什麼大事。但可能比遺憾更安全。當然,有命令行訪問的人可以執行他們想要的任何ruby。但是,然後你編寫你的工具,然後你最終以某種方式使用它,也許是對它進行脫殼,使得它最終被從_remote_用戶輸入傳入的參數調用,哎呀,你剛剛給了遠程用戶RCE,而你'd可能永遠不會意識到它,因爲它經歷了幾個步驟,並且你忘記了命令行的arg結束了評估。 – jrochkind