Verhindert, dass die Funktion "input" Funktionen aufruft oder auf Variablen zugreift

8

Unter Berücksichtigung des folgenden Codes

%Vor%

Wenn der Benutzer [1 2 3] eingibt, wird der Variable x dieser numerische Vektor zugewiesen. Wenn sie {1, [2 3], 'abc'} eingeben, wird die Variable x in ähnlicher Weise ein Zellenarray sein, das diese Werte enthält. Gut.

Wenn der Benutzer nun [sqrt(2) sin(pi/3)] eingibt, wird der Variablen x die resultierenden Werte zugewiesen: [1.414213562373095 0.866025403784439] . Dies liegt daran, dass die bereitgestellten Daten von input : < sind / p>

  

input Eingabeaufforderung für Benutzereingabe.
result = input(prompt) zeigt die Zeichenfolge prompt auf dem Bildschirm an und wartet       Für die Eingabe über die Tastatur bewertet alle Ausdrücke in der Eingabe .       und gibt den Wert in result zurück. [...]

Dies kann zu Problemen führen. Was passiert beispielsweise, wenn der Benutzer addpath('c:\path\to\folder') als Eingabe eingibt? Da die Eingabe ausgewertet wird, ist es tatsächlich ein Befehl, der von Matlab ausgeführt wird. So kann der Benutzer einen Pfad zum Pfad hinzufügen. Schlimmer noch, wenn sie path('') eingeben, wird der Pfad effektiv in nichts geändert, und Matlab hört auf, ordnungsgemäß zu funktionieren.

Eine weitere potentielle Quelle von Problemen ist das

  

[...] Um Ausdrücke auszuwerten, greift input auf Variablen im aktuellen Arbeitsbereich zu .

Wenn beispielsweise der Benutzer fprintf(1,'%f', varname) und varname ein vorhandenes numerisches Array eingibt, kennt der Benutzer den aktuellen Wert.

Dieses Verhalten ist wahrscheinlich von Entwurf. Benutzer eines Matlab-Programms sind vertrauenswürdig, wenn sie Daten eingeben, ähnlich wie vertrauenswürdig, wenn sie nicht Control - C drücken, um das Programm anzuhalten (und dann alle Befehle auszuführen oder alle Variablen zu inspizieren) sie mögen!).

Aber in bestimmten Fällen möchte der Programmierer vielleicht eine "sicherere" input Funktion haben, mit der ich meine

  1. verhindert bei der Benutzerbewertung Funktionsaufrufe Eingabe ; und
  2. Verhindert, dass die Eingabe auf Variablen des Programms zugreift.

Also wäre [1 2] eine gültige Eingabe, aber [sqrt(2) sin(pi/3)] oder path'' würde nicht wegen der 1; und [1 2 3 varname(1)] würde auch wegen Punkt 2 ungültig sein.

    
Luis Mendo 14.10.2015, 11:26
quelle

2 Antworten

6

Ich habe eine nicht sehr zufriedenstellende Lösung gefunden (und ich würde gerne über eine bessere lesen). Es verwendet eine semi-dokumentierte -Funktion und impliziert das Speichern der Benutzereingaben in einer temporären Datei . Die Funktion, auf die in Yair Altmans Blog verwiesen wird, ist getcallinfo . Laut help getcallinfo :

  

getcallinfo

     

Gibt aufgerufene Funktionen und ihre erste und letzte Zeile zurück       Diese Funktion wird nicht unterstützt und kann ohne oder ohne entfernt werden       Hinweis in einer zukünftigen Version.

Diese Funktion löst Problem 1 (Funktionsaufrufe verhindern). Wie für Problem 2 (Verhindern des Zugriffs auf Variablen) würde es ausreichen, die Eingabe innerhalb einer Funktion zu bewerten, so dass sie andere Variablen nicht sehen kann. Anscheinend (siehe Beispiel 2 unten) erkennt getcallinfo nicht nur die aufgerufenen Funktionen, sondern auch Variablen . Wie auch immer, es ist wahrscheinlich eine gute Idee, die Auswertung im isolierten Bereich einer Funktion durchzuführen.

Die Prozedur ist dann:

  1. Verwenden Sie die Zeichenfolgenversion von input , um eine Auswertung zu verhindern:

    %Vor%
  2. Speichern Sie die Zeichenfolge in einer Datei:

    %Vor%
  3. Überprüfen Sie die Eingabezeichenfolge mit getcallinfo , um mögliche Funktionsaufrufe zu erkennen:

    %Vor%

wobei evalinput die folgende Funktion ist

%Vor%

Beispiel 1

Betrachten Sie

%Vor%

mit Benutzereingabe

%Vor%

Dann

%Vor%

erzeugt ein nicht-leeres gci.calls.fcnCalls.names ,

%Vor%

sagt uns, dass die Benutzereingabe die Funktionen sqrt , sin und pi aufrufen würde, wenn sie ausgewertet würden. Beachten Sie, dass Operatoren wie / nicht als Funktionen erkannt werden.

Beispiel 2

%Vor%

Der Benutzer gibt

ein %Vor%

Dann

%Vor%

erzeugt

%Vor%

So werden Variablen von getcallinfo erkannt, als wären sie Funktionen.

    
Luis Mendo 14.10.2015 11:26
quelle
1

Wenn ich Ihre Frage richtig verstanden habe, ist es möglich, reguläre Ausdrücke zu verwenden, um das zu erreichen, was Sie versuchen zu tun.

Keine Funktions- oder Variablenaufrufe

Im einfachsten Fall wird überprüft, ob in der Eingabezeichenfolge alphabetische Zeichen enthalten sind. Der Ausdruck wäre dann für x mit Eingabe:

%Vor%

Das allein funktioniert für die wenigen Beispiele, die Sie oben geben.

Zulassen einiger Funktionen oder Variablen

Angenommen, Sie möchten, dass der Benutzer auf einige Variablen oder Funktionen zugreifen kann, vielleicht auf einfache trigonometrische Funktionen oder auf pi oder was haben Sie, dann ist es nicht mehr so ​​einfach. Ich habe mit einem Ausdruck wie unten gespielt:

expr = '(?!cos\(|pi|sin\()[a-zA-Z]+

Aber es tut nicht ganz, was erwartet wird. Es entspricht in( in sin . Wenn Sie Regex besser als ich kennen, können Sie das massieren, um richtig zu arbeiten.

Anderenfalls wäre dies eine Alternative:

%Vor%

, damit Sie die Zeichenfolgen entfernen, an denen Sie interessiert sind.

Hoffe, das hilft.

Update: Um imaginäre / exp-Werte und Pfade zu ermöglichen

Der neue passende Ausdruck wird

%Vor%

Dies ignoriert I / I und E / E (Sie können dies nach Belieben erweitern). Sie können auch eine Zwei-Zeichen-Grenze machen, indem Sie zu \{2,} wechseln, obwohl ich Personen immer noch ein Zeichen anonyme Funktionen haben kann.

Der andere Teil, der auf Eingabe überprüft wird, lautet:

%Vor%

Jetzt können Sie benutzerdefinierte Funktionen ausschließen (Sie können dies immer als ein Array haben und sie durch ein | verbinden) und Pfade.

Hier sind ein paar Beispiele, die zusammen mit dem Üblichen getestet wurden:

Passt

%Vor%

Fehler

%Vor%     
pragmatist1 15.10.2015 04:44
quelle

Tags und Links