Index: /trunk/rbtools/scripts/post-review
===================================================================
--- /trunk/rbtools/scripts/post-review	(revision 1980)
+++ /trunk/rbtools/scripts/post-review	(working copy)
@@ -9,6 +9,7 @@
 import re
 import simplejson
 import socket
+import stat
 import subprocess
 import sys
 import tempfile
@@ -1626,7 +1627,12 @@
         """
         diff_cmd = ["diff", "-urNp", old_file, new_file]
         # Diff returns "1" if differences were found.
-        dl = execute(diff_cmd, extra_ignore_errors=(1,2)).splitlines(True)
+        dl = execute(diff_cmd, extra_ignore_errors=(1,2),
+                     translate_newlines=False)
+
+        # If the input file has ^M characters at end of line, lets ignore them.
+        dl = dl.replace('\r\r\n', '\r\n')
+        dl = dl.splitlines(True)
 
         cwd = os.getcwd()
         if depot_path.startswith(cwd):
@@ -1690,16 +1696,13 @@
 
     def _write_file(self, depot_path, tmpfile):
         """
-        Grabs a file from Perforce and writes it to a temp file. We do this
-        wrather than telling p4 print to write it out in order to work around
-        a permissions bug on Windows.
+        Grabs a file from Perforce and writes it to a temp file. p4 print sets
+        the file readonly and that causes a later call to unlink fail. So we
+        make the file read/write.
         """
         debug('Writing "%s" to "%s"' % (depot_path, tmpfile))
-        data = execute(["p4", "print", "-q", depot_path])
-
-        f = open(tmpfile, "w")
-        f.write(data)
-        f.close()
+        execute(["p4", "print", "-o", tmpfile, "-q", depot_path])
+        os.chmod(tmpfile, stat.S_IWRITE)
 
     def _depot_to_local(self, depot_path):
         """
@@ -2043,7 +2046,7 @@
 
 
 def execute(command, env=None, split_lines=False, ignore_errors=False,
-            extra_ignore_errors=()):
+            extra_ignore_errors=(), translate_newlines=True):
     """
     Utility function to execute a command and return the output.
     """
@@ -2066,7 +2069,7 @@
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT,
                              shell=False,
-                             universal_newlines=True,
+                             universal_newlines=translate_newlines,
                              env=env)
     else:
         p = subprocess.Popen(command,
@@ -2075,7 +2078,7 @@
                              stderr=subprocess.STDOUT,
                              shell=False,
                              close_fds=True,
-                             universal_newlines=True,
+                             universal_newlines=translate_newlines,
                              env=env)
     if split_lines:
         data = p.stdout.readlines()
Index: /trunk/reviewboard/diffviewer/diffutils.py
===================================================================
--- /trunk/reviewboard/diffviewer/diffutils.py	(revision 1980)
+++ /trunk/reviewboard/diffviewer/diffutils.py	(working copy)
@@ -57,35 +57,37 @@
                 (compat_version))
 
 
+def convert_line_endings(data):
+    # Files without a trailing newline come out of Perforce (and possibly
+    # other systems) with a trailing \r. Diff will see the \r and
+    # add a "\ No newline at end of file" marker at the end of the file's
+    # contents, which patch understands and will happily apply this to
+    # a file with a trailing \r.
+    #
+    # The problem is that we normalize \r's to \n's, which breaks patch.
+    # Our solution to this is to just remove that last \r and not turn
+    # it into a \n.
+    #
+    # See http://code.google.com/p/reviewboard/issues/detail?id=386
+    # and http://reviews.review-board.org/r/286/
+    if data == "":
+        return ""
+
+    if data[-1] == "\r":
+        data = data[:-1]
+
+    temp = data.replace('\r\r\n', '\n')
+    temp = data.replace('\r\n', '\n')
+    temp = temp.replace('\r', '\n')
+    return temp
+
+
 def patch(diff, file, filename):
     """Apply a diff to a file.  Delegates out to `patch` because noone
        except Larry Wall knows how to patch."""
 
     log_timer = log_timed("Patching file %s" % filename)
 
-    def convert_line_endings(data):
-        # Files without a trailing newline come out of Perforce (and possibly
-        # other systems) with a trailing \r. Diff will see the \r and
-        # add a "\ No newline at end of file" marker at the end of the file's
-        # contents, which patch understands and will happily apply this to
-        # a file with a trailing \r.
-        #
-        # The problem is that we normalize \r's to \n's, which breaks patch.
-        # Our solution to this is to just remove that last \r and not turn
-        # it into a \n.
-        #
-        # See http://code.google.com/p/reviewboard/issues/detail?id=386
-        # and http://reviews.review-board.org/r/286/
-        if data == "":
-            return ""
-
-        if data[-1] == "\r":
-            data = data[:-1]
-
-        temp = data.replace('\r\n', '\n')
-        temp = temp.replace('\r', '\n')
-        return temp
-
     if diff.strip() == "":
         # Someone uploaded an unchanged file. Return the one we're patching.
         return file
@@ -225,6 +227,7 @@
             log_timer = log_timed("Fetching file '%s' r%s from %s" %
                                   (file, revision, repository))
             data = tool.get_file(file, revision)
+            data = convert_line_endings(data)
             log_timer.done()
             return data
 
