Repository: ansible/ansible

Issue:
Parsing error in Ansible 1.9.4 in debug module if string contains special sequences
##### Issue Type:

 Bug Report
##### Ansible Version:

```
ansible 1.9.4
```
##### Ansible Configuration:

Default
##### Environment:

Ubuntu 15.04
Python 2.7.9
##### Summary:

Execution of playbook fails with parsing error when trying to print debug variable containing sequence of special characters.
##### Steps To Reproduce:

_file.txt_

```
{%‘’
```

_site.yml_

```
- name: test
  hosts: 127.0.0.1
  connection: local
  gather_facts: false
  tasks:
    - shell: cat file.txt
      register: out

    - debug: var=out.stdout
```

_execution_

```
$ ansible-playbook -i inventory/ansible-hosts site.yml                                     
```
##### Expected Results:

Successful debug print.
##### Actual Results:

Ansible fails with parsing error.

```
$ ansible-playbook -i inventory/ansible-hosts site.yml     

PLAY [test] ******************************************************************* 

TASK: [shell cat log1] ******************************************************** 
changed: [127.0.0.1]

TASK: [debug var=out.stdout] ************************************************** 
fatal: [127.0.0.1] => Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/ansible/runner/__init__.py", line 586, in _executor
    exec_rc = self._executor_internal(host, new_stdin)
  File "/usr/local/lib/python2.7/dist-packages/ansible/runner/__init__.py", line 789, in _executor_internal
    return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port, complex_args=complex_args)
  File "/usr/local/lib/python2.7/dist-packages/ansible/runner/__init__.py", line 1036, in _executor_internal_inner
    result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
  File "/usr/local/lib/python2.7/dist-packages/ansible/runner/action_plugins/debug.py", line 54, in run
    results = template.template(self.basedir, args['var'], inject, convert_bare=True)
  File "/usr/local/lib/python2.7/dist-packages/ansible/utils/template.py", line 126, in template
    raise errors.AnsibleError("Failed to template %s: %s" % (varname, str(e)))
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2018' in position 1198823: ordinal not in range(128)


FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/bubo/site.retry

127.0.0.1                  : ok=1    changed=1    unreachable=1    failed=0   
```

Interestingly enough, Ansible produces different error when `file.txt` contains only `{%` (without backquotes)

```
$ ansible-playbook -i inventory/ansible-hosts site.yml

PLAY [test] ******************************************************************* 

TASK: [shell cat txt] ********************************************************* 
changed: [127.0.0.1]

TASK: [debug var=out.stdout] ************************************************** 
fatal: [127.0.0.1] => Failed to template {{out.stdout}}: Failed to template {%: template error while templating string: tag name expected

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/bubo/site.retry

127.0.0.1                  : ok=1    changed=1    unreachable=1    failed=0   
```

Note that calling `debug` module with `msg` parameter instead of `var` or using jinja `escape` filter doesn't help.



Discussion:

Resolving patch:
diff --git a/lib/ansible/utils/template.py b/lib/ansible/utils/template.py
--- a/lib/ansible/utils/template.py
+++ b/lib/ansible/utils/template.py
@@ -119,7 +119,7 @@ def template(basedir, varname, templatevars, lookup_fatal=True, depth=0, expand_
                 varname = "{{%s}}" % varname
 
         if isinstance(varname, basestring):
-            if '{{' in varname or '{%' in varname:
+            if ('{{' in varname and '}}' in varname ) or ( '{%' in varname and '%}' in varname ):
                 try:
                     varname = template_from_string(basedir, varname, templatevars, fail_on_undefined)
                 except errors.AnsibleError, e:


Test patch: