Merge lp:~facundo/ubuntuone-client/lr-stop-nonutf8 into lp:ubuntuone-client

Proposed by Facundo Batista
Status: Merged
Approved by: Facundo Batista
Approved revision: 1111
Merged at revision: 1119
Proposed branch: lp:~facundo/ubuntuone-client/lr-stop-nonutf8
Merge into: lp:ubuntuone-client
Diff against target: 117 lines (+66/-6)
2 files modified
tests/syncdaemon/test_localrescan.py (+32/-1)
ubuntuone/syncdaemon/local_rescan.py (+34/-5)
To merge this branch: bzr merge lp:~facundo/ubuntuone-client/lr-stop-nonutf8
Reviewer Review Type Date Requested Status
Facundo Batista (community) Approve
Natalia Bidart (community) Approve
Review via email: mp+72452@code.launchpad.net

Commit message

Ignore non utf8 paths in LR (LP: #696901).

Description of the change

Ignore non utf8 paths in LR.

The one that should check if the path is valid is LocalRescan. It can't be done in the signals processors (that are close to real validation, in the freeze_commit stage).

The reason for this is that if LR finds an invalid path it needs to ignore it; in files there is no problem, but for directories it shouldn't scan that directory later.

So, I added a function in LR, very similar to the one in in platform/linux/filesystem_notification.py; didn't use that because this is more platform independant, will all go away when put everything in unicode, and most importantly because don't want to send invalid notifications and don't write in the invalid log for *every* local rescan.

Tests included, and also added logging when ignoring the path because of symlink.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Looks great!

review: Approve
Revision history for this message
Facundo Batista (facundo) wrote :

Approving with one review.

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (252.9 KiB)

The attempt to merge lp:~facundo/ubuntuone-client/lr-stop-nonutf8 into lp:ubuntuone-client failed. Below is the output from the failed tests.

/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
  testing autoconf2.50... not found.
  testing autoconf... found 2.67
checking for automake >= 1.10...
  testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
  testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
  testing intltoolize... found 0.41.1
checking for pkg-config >= 0.14.0...
  testing pkg-config... found 0.25
checking for gtk-doc >= 1.0...
  testing gtkdocize... found 1.17
Checking for required M4 macros...
Checking for forbidden M4 macros...
Processing ./configure.ac
Running libtoolize...
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
Running gtkdocize...
Running aclocal-1.11...
Running autoconf...
Running autoheader...
Running automake-1.11...
Running ./configure --enable-gtk-doc --enable-debug ...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... mawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to ...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/syncdaemon/test_localrescan.py'
2--- tests/syncdaemon/test_localrescan.py 2011-08-12 15:26:13 +0000
3+++ tests/syncdaemon/test_localrescan.py 2011-08-22 15:52:23 +0000
4@@ -1,7 +1,7 @@
5 # Author: Facundo Batista <facundo@canonical.com>
6 # Author: Natalia Bidart <natalia.bidart@canonical.com>
7 #
8-# Copyright 2009 Canonical Ltd.
9+# Copyright 2009-2011 Canonical Ltd.
10 #
11 # This program is free software: you can redistribute it and/or modify it
12 # under the terms of the GNU General Public License version 3, as published
13@@ -617,6 +617,37 @@
14
15 yield self.lr.start()
16 self.assertEqual(self.eq.pushed, [])
17+ self.assertTrue(self.handler.check_info("Ignoring path",
18+ "symlink", symlpath))
19+
20+ @skipIfOS('win32', "Windows paths are already unicode, "
21+ "can't make this explode there")
22+ @defer.inlineCallbacks
23+ def test_disc_non_utf8_file(self):
24+ """Test having a utf8 file."""
25+ # create a broken path
26+ path = os.path.join(self.share.path, "non utf8 \xff path")
27+ with open_file(path, "w") as fh:
28+ fh.write("broken")
29+
30+ yield self.lr.start()
31+ self.assertEqual(self.eq.pushed, [])
32+ self.assertTrue(self.handler.check_info("Ignoring path",
33+ "invalid (non utf8)"))
34+
35+ @skipIfOS('win32', "Windows paths are already unicode, "
36+ "can't make this explode there")
37+ @defer.inlineCallbacks
38+ def test_disc_non_utf8_dir(self):
39+ """Test having a utf8 dir."""
40+ # create a broken path
41+ path = os.path.join(self.share.path, "non utf8 \xff path")
42+ make_dir(path)
43+
44+ yield self.lr.start()
45+ self.assertEqual(self.eq.pushed, [])
46+ self.assertTrue(self.handler.check_info("Ignoring path",
47+ "invalid (non utf8)"))
48
49 @defer.inlineCallbacks
50 def test_disc_more_dir_normal(self):
51
52=== modified file 'ubuntuone/syncdaemon/local_rescan.py'
53--- ubuntuone/syncdaemon/local_rescan.py 2011-08-10 15:03:17 +0000
54+++ ubuntuone/syncdaemon/local_rescan.py 2011-08-22 15:52:23 +0000
55@@ -2,7 +2,7 @@
56 #
57 # Author: Facundo Batista <facundo@canonical.com>
58 #
59-# Copyright 2009 Canonical Ltd.
60+# Copyright 2009-2011 Canonical Ltd.
61 #
62 # This program is free software: you can redistribute it and/or modify it
63 # under the terms of the GNU General Public License version 3, as published
64@@ -56,6 +56,26 @@
65 log_warning = functools.partial(lr_logger.log, logging.WARNING)
66
67
68+def is_valid_name(path):
69+ """Tell if the name is valid.
70+
71+ This checks for the bytes in the path to be UTF8 valid before let them
72+ get into Syncdaemon.
73+
74+ There is a similar check in platform/linux/filesystem_notification.py; we
75+ don't use that because this is more platform independant, will all go away
76+ when put everything in unicode, and most importantly because don't want to
77+ send invalid notifications and don't write in the invalid log for *every*
78+ local rescan.
79+ """
80+ try:
81+ path.decode("utf8")
82+ except UnicodeDecodeError:
83+ return False
84+ else:
85+ return True
86+
87+
88 class LocalRescan(object):
89 """Local re-scanner.
90
91@@ -644,13 +664,22 @@
92 for something in dircontent:
93 fullname = os.path.join(dirpath, something)
94 stat_result = get_stat(fullname)
95- if stat_result is None or is_link(fullname):
96- continue
97- elif not access(fullname):
98+ if stat_result is None:
99+ # gone between the listdir and now
100+ continue
101+ if is_link(fullname):
102+ log_info("Ignoring path as it's a symlink: %r", fullname)
103+ continue
104+ if not is_valid_name(fullname):
105+ m = "Ignoring path because it's invalid (non utf8): %r"
106+ log_info(m, fullname)
107+ continue
108+ if not access(fullname):
109 log_warning("Ignoring path as we don't have enough "
110 "permissions to track it: %r", fullname)
111 continue
112- elif stat.S_ISDIR(stat_result.st_mode):
113+
114+ if stat.S_ISDIR(stat_result.st_mode):
115 dnames.append(something)
116 elif stat.S_ISREG(stat_result.st_mode):
117 fnames.append(something)

Subscribers

People subscribed via source and target branches