Quels sont les dangers de la fonction eval(parse(...))?
Il y a plusieurs questions sur la façon d'éviter d'utiliser eval(parse(...))
Qui déclenche les questions:
- Pourquoi, en particulier, devrait
eval(parse())
- elle être évitée? - Et surtout, Quels en sont les dangers?
- Sont-il dangereux si le code n'est pas utilisé dans la production? (Je suis en train de penser, tout risque de retour des résultats inattendus. En clair, si vous n'êtes pas prudent sur ce que vous analysez, vous aurez des problèmes. Mais est-ce plus dangereux que d'être bâclée avec
get()
?)
- Sont-il dangereux si le code n'est pas utilisé dans la production? (Je suis en train de penser, tout risque de retour des résultats inattendus. En clair, si vous n'êtes pas prudent sur ce que vous analysez, vous aurez des problèmes. Mais est-ce plus dangereux que d'être bâclée avec
- Je ne sais pas si je vais avoir le temps de créer un bon exemple/écrire une réponse, mais mes maux de tête dans cette direction ont eu plus à faire avec
eval()
généralement que aveceval(parse())
. Le problème aveceval()
est qu'il essaie de suivre une certaine base, mais souvent difficiles à comprendre des règles sur les cadres dans lesquels l'expression est évaluée, et ceux-ci peuvent souvent vous mordre quand vous commencez à utiliser des constructions de code de manière plus complexe que l'auteur à l'origine de la pensée de ... obeautifulcode.com/R/How-R-Searches-And-Finds-Stuff - cette question semble être de frapper beaucoup de résultats de recherche. Si vous souhaitez revenir sur votre commentaire ci-dessus, j'aimerais entendre plus de vos pensées, je suis sûr que d'autres seraient ainsi
- Saporta, vous semblent profiter de l'aide de
data.table
. Fait intéressant, je suis tombé sur la poste où est expliqué queeval
peut être plus rapide queget
, dans certains cas, avecdata.table
Vous devez vous connecter pour publier un commentaire.
La plupart des arguments contre la
eval(parse(...))
surviennent pas en raison de problèmes de sécurité, après tout, aucune réclamation n'est faite à propos de R un approvisionnement sûr de l'interface d'exposer à l'Internet, mais plutôt parce que ce code est généralement de faire des choses qui peut être accompli en utilisant moins obscur méthodes, c'est à dire des méthodes qui sont à la fois plus rapide et plus humain analyser-mesure. Le langage R est censé être de haut niveau, de sorte que la préférence des connaisseurs (et je ne me considère pas dans le groupe) est de voir le code qui est à la fois compact et expressive.Ainsi, le danger est que
eval(parse(..))
est une porte dérobée méthode de contourner le manque de connaissances et de l'espoir dans la levée de cet obstacle est que les gens vont améliorer leur utilisation de la R de la langue. La porte reste ouverte, mais l'espoir est de plus expressive utilisez d'autres fonctionnalités. Carl Witthoft la question plus tôt aujourd'hui illustré en ne sachant pas que leget
fonction était disponible, et la la question qu'il a lié pour révélé un manque de compréhension de la façon la[[
fonction comportés (et comment$
a été plus limité que[[
). Dans les deux cas, uneeval(parse(..))
solution pourrait être construit, mais il était moins agiles et moins claire que l'autre.Les préoccupations en matière de sécurité seulement vraiment se poser si vous commencez à appeler eval sur les cordes qu'un autre utilisateur est passé pour vous. C'est une grosse affaire si vous créez une application qui s'exécute R dans le fond, mais pour l'analyse de données lorsque vous écrivez du code à exécuter par vous-même, alors vous ne devriez pas avoir à vous soucier de l'effet de
eval
sur la sécurité.Certains autres problèmes avec
eval(parse(
bien.Tout d'abord, le code utilisant eval-analyser est généralement beaucoup plus difficile à déboguer que les non-analysée code, ce qui est problématique parce que le débogage des logiciels est deux fois plus difficile que la rédaction en premier lieu.
Voici une fonction avec une erreur en elle.
Je suis bête, j'ai oublié l'opérateur deux points et créé mon vecteur tort. Si j'essaie et la source de cette fonction, puis R avis le problème et renvoie une erreur, de me pointer à mon erreur.
Voici le eval-analyser version.
Ce sera source, parce que l'erreur est à l'intérieur d'une chaîne valide. C'est seulement plus tard, quand nous venons à exécuter le code de l'erreur est levée. Ainsi, en utilisant eval-analyser, nous avons perdu la source de l'erreur au moment de la vérification de la capacité.
Je pense aussi que cette deuxième version de la fonction est beaucoup plus difficile à lire.
L'autre problème avec eval-analyser, c'est qu'il est beaucoup plus lent que le code exécuté. Comparer
et
Habituellement, il y a une meilleure façon de l'informatique sur la langue " que de travailler avec un code-strings; evalparse lourds-code a besoin de beaucoup de protection pour garantir un bon de sortie, dans mon expérience.
La même tâche peut généralement être résolu par un travail sur la R du code dans un langage objet directement; Hadley Wickham a un guide utile sur la méta-programmation en R ici:
La defmacro() fonction dans le gtools bibliothèque est mon préféré remplacer (pas de demi-assed R pun intended) pour la evalparse construire
L'avantage de cette méthode est que vous avez la garantie de récupérer un point de vue syntaxique-juridique R code. En savoir plus sur cette fonction utile peut être trouvé ici:
Espère que ça aide!
Il y a toutes sortes d'exploits que l'on peut prendre avantage de si eval est utilisé de manière inappropriée.
En d'autres termes, le plus grand danger de
eval()
est le potentiel de l'injection de code dans votre application. L'utilisation deeval()
peut également provoquer des problèmes de performances dans certaines langues, selon ce qui est utilisé pour.Spécifiquement dans R, c'est probablement parce que vous pouvez utiliser
get()
en place deeval(parse())
et vos résultats seront les mêmes, sans avoir à recourir àeval()
T <- FALSE; F <- TRUE
,rm(list=ls())
,system("rm -rf your_directories")
,source("http://.../virus.R")
.eval
(eval.secure
) dans le RAppArmor package qui s'exécute dans un bac à sable, et ne peut pas exercer les droits de super-utilisateur, à moins que le processus parent a eux.eval.secure
parse()
. L' (valide) entrée deeval
est presque jamais une "chaîne".