-2

I have really weird syntax error. In the first time the code works fine but after that it doesnt works.

MailName={}
string = ""
#pdb.set_trace()
fp=open("C:\\Users\\Dvir\\Dropbox\\chat\\cred.txt","a+")
#pdb.set_trace()

try:
    string=fp.read()

except:
    string=""

if (string !=""):
    MailName = eval(string)

The problematic code is:

MailName = eval(string)

The syntax error:

MailName = eval(string)   File "<string>", line 2
{'familyname': 'josh', 'pass': 'UGGlXJCpl', 'email': 'chat@gmail.com', 'n ame': 'justin'}
^ SyntaxError: invalid syntax

When I use that part of code in the first time it works perfecly but after that it shows me syntax error which is weird because it's a valid dictionary.

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
user1341970
  • 449
  • 2
  • 7
  • 15
  • is your file multiline? if each line looks like {...} without an ending comma, that's where your invalid syntax may come up, since your MailName could look like { {...} {...} } which is NOT a valid dictionary. other than that, provide some more information – Samuele Mattiuzzo Jan 04 '13 at 09:17
  • 2
    Why are you using `eval` in the first place? If you must evaluate arbitrary Python literals, at least use `ast.literal_eval` instead, which protects against code injection attacks (what happens if someone edits `cred.txt` to say `os.system("deltree /Y C:\")` with your code?) _and_ sometimes gives better error messages to boot. But usually, evaluating Python literals is a bad idea. If you want to store data, use an human-readable interchange format like JSON or YAML, or a compact and flexible one like pickle, not `repr` and `eval`. – abarnert Jan 04 '13 at 09:20
  • 1
    Also, why do you set `MailName={}` and `string=""` up at the top when you're going to overwrite them before you ever read them? This isn't C, where you have to declare all your variables at the top; in Python, the only effect that usually has is to disguise bugs caused by typos. – abarnert Jan 04 '13 at 09:23
  • Finally, what do you mean by "in the first time"? The first time you run the program it works, the second time it doesn't? Or is there some loop in the program? Does the loop just re-eval the same string, or read from the same file object, or open the file and read again, or what? (PS, `string` is the name of a standard-library module, so you shouldn't use it as the name of a variable; it will lead to confusion.) – abarnert Jan 04 '13 at 09:28

1 Answers1

7

I would store the data in JSON and load it using json.load(file object) instead - this is safer than using eval()


Quoted from this answer:

eval() will allow malicious data to compromise your entire system, kill your cat, eat your dog and make love to your wife.

There was recently a thread about how to do this kind of thing safely on the python-dev list, and the conclusions were:

It's really hard to do this properly.
It requires patches to the python interpreter to block many classes of attacks.
Don't do it unless you really want to.

You could format your text file as follows: (cred.txt)

{
    "familyname": "josh", 
    "email": "chat@gmail.com", 
    "name": "justin", 
    "pass": "UGGlXJCpl"
}

And then load it like this:

>>> with open('cred.txt', 'rb') as f:
>>>     data = json.load(f)
>>>     print data
{'familyname': 'josh', 'pass': 'UGGlXJCpl', 'email': 'chat@gmail.com', 'name': 'justin'}
Community
  • 1
  • 1
Alex L
  • 8,748
  • 5
  • 49
  • 75
  • Why the downvote? Is `eval()` not considered bad practice? – Alex L Jan 04 '13 at 09:19
  • I gave you a +1 myself. But this would be a better answer if you explained _why_ it was safer instead of just baldly stating it. (And probably telling the OP how to store the data in JSON in the first place might be helpful—his existing data looks JSON-y, but it's not valid JSON.) – abarnert Jan 04 '13 at 09:25
  • Also, it doesn't really directly answer the OP's question. To you or me, it's obvious why you answered this way, but I could imagine the OP or another novice might downvote you because to him it seems totally irrelevant… – abarnert Jan 04 '13 at 09:27
  • what makes ast.literal_eval more secure than eval? – user1341970 Jan 04 '13 at 09:29
  • @abarnert Cheers for the feedback, I've expanded upon my answer. – Alex L Jan 04 '13 at 09:31
  • 1
    @user1341970: It's hard to describe in a comment, beyond what I already said above: `eval('os.system("deltree /Y C:/")')` will delete everything on your hard drive; `ast.literal_eval('os.system("deltree /Y C:/")' will raise a `ValueError`. The idea is that `literal_eval` only works on literals—numbers, strings, `list`s, etc., while `eval` works on _any_ Python expression. – abarnert Jan 04 '13 at 09:32
  • @AlexL: Well, I already gave you a +1, so I can't +1 it again. But hopefully others will. :) – abarnert Jan 04 '13 at 09:33
  • 1
    @abarnert No worries, I'm not concerned about the rep, just don't want to see `eval()` used in the wild! – Alex L Jan 04 '13 at 09:35
  • @AlexL: But what's the good of that "SENDPAYPALPASSWORDTOALEXL.EXE" program if nobody's using `eval()` in the wild? :) – abarnert Jan 04 '13 at 09:38