Merge lp:~percona-toolkit-dev/percona-toolkit/fix-password-comma-bug-886077 into lp:percona-toolkit/2.1

Proposed by Daniel Nichter
Status: Merged
Merged at revision: 263
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-password-comma-bug-886077
Merge into: lp:percona-toolkit/2.1
Diff against target: 996 lines (+297/-100)
26 files modified
bin/pt-archiver (+11/-6)
bin/pt-config-diff (+4/-1)
bin/pt-deadlock-logger (+11/-6)
bin/pt-duplicate-key-checker (+11/-6)
bin/pt-find (+11/-6)
bin/pt-fk-error-logger (+11/-6)
bin/pt-heartbeat (+11/-6)
bin/pt-index-usage (+11/-6)
bin/pt-kill (+4/-1)
bin/pt-log-player (+11/-6)
bin/pt-online-schema-change (+4/-1)
bin/pt-query-advisor (+4/-1)
bin/pt-query-digest (+11/-6)
bin/pt-show-grants (+11/-6)
bin/pt-slave-delay (+11/-6)
bin/pt-slave-find (+11/-6)
bin/pt-slave-restart (+11/-6)
bin/pt-table-checksum (+4/-1)
bin/pt-table-sync (+4/-1)
bin/pt-table-usage (+4/-1)
bin/pt-upgrade (+4/-1)
bin/pt-variable-advisor (+11/-6)
bin/pt-visual-explain (+11/-6)
docs/percona-toolkit.pod (+14/-0)
lib/DSNParser.pm (+6/-1)
t/lib/DSNParser.t (+80/-1)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-password-comma-bug-886077
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Review via email: mp+107250@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-archiver'
2--- bin/pt-archiver 2012-04-17 22:52:34 +0000
3+++ bin/pt-archiver 2012-05-24 17:33:24 +0000
4@@ -1454,6 +1454,8 @@
5 $Data::Dumper::Indent = 0;
6 $Data::Dumper::Quotekeys = 0;
7
8+my $dsn_sep = qr/(?<!\\),/;
9+
10 eval {
11 require DBI;
12 };
13@@ -1508,7 +1510,8 @@
14 my %final_props;
15 my $opts = $self->{opts};
16
17- foreach my $dsn_part ( split(/,/, $dsn) ) {
18+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
19+ $dsn_part =~ s/\\,/,/g;
20 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
21 $given_props{$prop_key} = $prop_val;
22 }
23@@ -1567,12 +1570,14 @@
24 sub as_string {
25 my ( $self, $dsn, $props ) = @_;
26 return $dsn unless ref $dsn;
27- my %allowed = $props ? map { $_=>1 } @$props : ();
28+ my @keys = $props ? @$props : sort keys %$dsn;
29 return join(',',
30- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
31- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
32- grep { !$props || $allowed{$_} }
33- sort keys %$dsn );
34+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
35+ grep {
36+ exists $self->{opts}->{$_}
37+ && exists $dsn->{$_}
38+ && defined $dsn->{$_}
39+ } @keys);
40 }
41
42 sub usage {
43
44=== modified file 'bin/pt-config-diff'
45--- bin/pt-config-diff 2012-04-03 19:42:45 +0000
46+++ bin/pt-config-diff 2012-05-24 17:33:24 +0000
47@@ -1053,6 +1053,8 @@
48 $Data::Dumper::Indent = 0;
49 $Data::Dumper::Quotekeys = 0;
50
51+my $dsn_sep = qr/(?<!\\),/;
52+
53 eval {
54 require DBI;
55 };
56@@ -1107,7 +1109,8 @@
57 my %final_props;
58 my $opts = $self->{opts};
59
60- foreach my $dsn_part ( split(/,/, $dsn) ) {
61+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
62+ $dsn_part =~ s/\\,/,/g;
63 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
64 $given_props{$prop_key} = $prop_val;
65 }
66
67=== modified file 'bin/pt-deadlock-logger'
68--- bin/pt-deadlock-logger 2012-04-03 19:42:45 +0000
69+++ bin/pt-deadlock-logger 2012-05-24 17:33:24 +0000
70@@ -1213,6 +1213,8 @@
71 $Data::Dumper::Indent = 0;
72 $Data::Dumper::Quotekeys = 0;
73
74+my $dsn_sep = qr/(?<!\\),/;
75+
76 eval {
77 require DBI;
78 };
79@@ -1267,7 +1269,8 @@
80 my %final_props;
81 my $opts = $self->{opts};
82
83- foreach my $dsn_part ( split(/,/, $dsn) ) {
84+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
85+ $dsn_part =~ s/\\,/,/g;
86 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
87 $given_props{$prop_key} = $prop_val;
88 }
89@@ -1326,12 +1329,14 @@
90 sub as_string {
91 my ( $self, $dsn, $props ) = @_;
92 return $dsn unless ref $dsn;
93- my %allowed = $props ? map { $_=>1 } @$props : ();
94+ my @keys = $props ? @$props : sort keys %$dsn;
95 return join(',',
96- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
97- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
98- grep { !$props || $allowed{$_} }
99- sort keys %$dsn );
100+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
101+ grep {
102+ exists $self->{opts}->{$_}
103+ && exists $dsn->{$_}
104+ && defined $dsn->{$_}
105+ } @keys);
106 }
107
108 sub usage {
109
110=== modified file 'bin/pt-duplicate-key-checker'
111--- bin/pt-duplicate-key-checker 2012-05-15 01:05:32 +0000
112+++ bin/pt-duplicate-key-checker 2012-05-24 17:33:24 +0000
113@@ -923,6 +923,8 @@
114 $Data::Dumper::Indent = 0;
115 $Data::Dumper::Quotekeys = 0;
116
117+my $dsn_sep = qr/(?<!\\),/;
118+
119 eval {
120 require DBI;
121 };
122@@ -977,7 +979,8 @@
123 my %final_props;
124 my $opts = $self->{opts};
125
126- foreach my $dsn_part ( split(/,/, $dsn) ) {
127+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
128+ $dsn_part =~ s/\\,/,/g;
129 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
130 $given_props{$prop_key} = $prop_val;
131 }
132@@ -1036,12 +1039,14 @@
133 sub as_string {
134 my ( $self, $dsn, $props ) = @_;
135 return $dsn unless ref $dsn;
136- my %allowed = $props ? map { $_=>1 } @$props : ();
137+ my @keys = $props ? @$props : sort keys %$dsn;
138 return join(',',
139- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
140- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
141- grep { !$props || $allowed{$_} }
142- sort keys %$dsn );
143+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
144+ grep {
145+ exists $self->{opts}->{$_}
146+ && exists $dsn->{$_}
147+ && defined $dsn->{$_}
148+ } @keys);
149 }
150
151 sub usage {
152
153=== modified file 'bin/pt-find'
154--- bin/pt-find 2012-04-03 19:42:45 +0000
155+++ bin/pt-find 2012-05-24 17:33:24 +0000
156@@ -28,6 +28,8 @@
157 $Data::Dumper::Indent = 0;
158 $Data::Dumper::Quotekeys = 0;
159
160+my $dsn_sep = qr/(?<!\\),/;
161+
162 eval {
163 require DBI;
164 };
165@@ -82,7 +84,8 @@
166 my %final_props;
167 my $opts = $self->{opts};
168
169- foreach my $dsn_part ( split(/,/, $dsn) ) {
170+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
171+ $dsn_part =~ s/\\,/,/g;
172 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
173 $given_props{$prop_key} = $prop_val;
174 }
175@@ -141,12 +144,14 @@
176 sub as_string {
177 my ( $self, $dsn, $props ) = @_;
178 return $dsn unless ref $dsn;
179- my %allowed = $props ? map { $_=>1 } @$props : ();
180+ my @keys = $props ? @$props : sort keys %$dsn;
181 return join(',',
182- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
183- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
184- grep { !$props || $allowed{$_} }
185- sort keys %$dsn );
186+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
187+ grep {
188+ exists $self->{opts}->{$_}
189+ && exists $dsn->{$_}
190+ && defined $dsn->{$_}
191+ } @keys);
192 }
193
194 sub usage {
195
196=== modified file 'bin/pt-fk-error-logger'
197--- bin/pt-fk-error-logger 2012-04-03 19:42:45 +0000
198+++ bin/pt-fk-error-logger 2012-05-24 17:33:24 +0000
199@@ -1130,6 +1130,8 @@
200 $Data::Dumper::Indent = 0;
201 $Data::Dumper::Quotekeys = 0;
202
203+my $dsn_sep = qr/(?<!\\),/;
204+
205 eval {
206 require DBI;
207 };
208@@ -1184,7 +1186,8 @@
209 my %final_props;
210 my $opts = $self->{opts};
211
212- foreach my $dsn_part ( split(/,/, $dsn) ) {
213+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
214+ $dsn_part =~ s/\\,/,/g;
215 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
216 $given_props{$prop_key} = $prop_val;
217 }
218@@ -1243,12 +1246,14 @@
219 sub as_string {
220 my ( $self, $dsn, $props ) = @_;
221 return $dsn unless ref $dsn;
222- my %allowed = $props ? map { $_=>1 } @$props : ();
223+ my @keys = $props ? @$props : sort keys %$dsn;
224 return join(',',
225- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
226- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
227- grep { !$props || $allowed{$_} }
228- sort keys %$dsn );
229+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
230+ grep {
231+ exists $self->{opts}->{$_}
232+ && exists $dsn->{$_}
233+ && defined $dsn->{$_}
234+ } @keys);
235 }
236
237 sub usage {
238
239=== modified file 'bin/pt-heartbeat'
240--- bin/pt-heartbeat 2012-05-17 14:54:36 +0000
241+++ bin/pt-heartbeat 2012-05-24 17:33:24 +0000
242@@ -1761,6 +1761,8 @@
243 $Data::Dumper::Indent = 0;
244 $Data::Dumper::Quotekeys = 0;
245
246+my $dsn_sep = qr/(?<!\\),/;
247+
248 eval {
249 require DBI;
250 };
251@@ -1815,7 +1817,8 @@
252 my %final_props;
253 my $opts = $self->{opts};
254
255- foreach my $dsn_part ( split(/,/, $dsn) ) {
256+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
257+ $dsn_part =~ s/\\,/,/g;
258 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
259 $given_props{$prop_key} = $prop_val;
260 }
261@@ -1874,12 +1877,14 @@
262 sub as_string {
263 my ( $self, $dsn, $props ) = @_;
264 return $dsn unless ref $dsn;
265- my %allowed = $props ? map { $_=>1 } @$props : ();
266+ my @keys = $props ? @$props : sort keys %$dsn;
267 return join(',',
268- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
269- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
270- grep { !$props || $allowed{$_} }
271- sort keys %$dsn );
272+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
273+ grep {
274+ exists $self->{opts}->{$_}
275+ && exists $dsn->{$_}
276+ && defined $dsn->{$_}
277+ } @keys);
278 }
279
280 sub usage {
281
282=== modified file 'bin/pt-index-usage'
283--- bin/pt-index-usage 2012-04-03 19:42:45 +0000
284+++ bin/pt-index-usage 2012-05-24 17:33:24 +0000
285@@ -28,6 +28,8 @@
286 $Data::Dumper::Indent = 0;
287 $Data::Dumper::Quotekeys = 0;
288
289+my $dsn_sep = qr/(?<!\\),/;
290+
291 eval {
292 require DBI;
293 };
294@@ -82,7 +84,8 @@
295 my %final_props;
296 my $opts = $self->{opts};
297
298- foreach my $dsn_part ( split(/,/, $dsn) ) {
299+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
300+ $dsn_part =~ s/\\,/,/g;
301 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
302 $given_props{$prop_key} = $prop_val;
303 }
304@@ -141,12 +144,14 @@
305 sub as_string {
306 my ( $self, $dsn, $props ) = @_;
307 return $dsn unless ref $dsn;
308- my %allowed = $props ? map { $_=>1 } @$props : ();
309+ my @keys = $props ? @$props : sort keys %$dsn;
310 return join(',',
311- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
312- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
313- grep { !$props || $allowed{$_} }
314- sort keys %$dsn );
315+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
316+ grep {
317+ exists $self->{opts}->{$_}
318+ && exists $dsn->{$_}
319+ && defined $dsn->{$_}
320+ } @keys);
321 }
322
323 sub usage {
324
325=== modified file 'bin/pt-kill'
326--- bin/pt-kill 2012-04-03 19:42:45 +0000
327+++ bin/pt-kill 2012-05-24 17:33:24 +0000
328@@ -1136,6 +1136,8 @@
329 $Data::Dumper::Indent = 0;
330 $Data::Dumper::Quotekeys = 0;
331
332+my $dsn_sep = qr/(?<!\\),/;
333+
334 eval {
335 require DBI;
336 };
337@@ -1190,7 +1192,8 @@
338 my %final_props;
339 my $opts = $self->{opts};
340
341- foreach my $dsn_part ( split(/,/, $dsn) ) {
342+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
343+ $dsn_part =~ s/\\,/,/g;
344 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
345 $given_props{$prop_key} = $prop_val;
346 }
347
348=== modified file 'bin/pt-log-player'
349--- bin/pt-log-player 2012-04-03 19:42:45 +0000
350+++ bin/pt-log-player 2012-05-24 17:33:24 +0000
351@@ -2008,6 +2008,8 @@
352 $Data::Dumper::Indent = 0;
353 $Data::Dumper::Quotekeys = 0;
354
355+my $dsn_sep = qr/(?<!\\),/;
356+
357 eval {
358 require DBI;
359 };
360@@ -2062,7 +2064,8 @@
361 my %final_props;
362 my $opts = $self->{opts};
363
364- foreach my $dsn_part ( split(/,/, $dsn) ) {
365+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
366+ $dsn_part =~ s/\\,/,/g;
367 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
368 $given_props{$prop_key} = $prop_val;
369 }
370@@ -2121,12 +2124,14 @@
371 sub as_string {
372 my ( $self, $dsn, $props ) = @_;
373 return $dsn unless ref $dsn;
374- my %allowed = $props ? map { $_=>1 } @$props : ();
375+ my @keys = $props ? @$props : sort keys %$dsn;
376 return join(',',
377- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
378- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
379- grep { !$props || $allowed{$_} }
380- sort keys %$dsn );
381+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
382+ grep {
383+ exists $self->{opts}->{$_}
384+ && exists $dsn->{$_}
385+ && defined $dsn->{$_}
386+ } @keys);
387 }
388
389 sub usage {
390
391=== modified file 'bin/pt-online-schema-change'
392--- bin/pt-online-schema-change 2012-05-17 14:54:36 +0000
393+++ bin/pt-online-schema-change 2012-05-24 17:33:24 +0000
394@@ -1136,6 +1136,8 @@
395 $Data::Dumper::Indent = 0;
396 $Data::Dumper::Quotekeys = 0;
397
398+my $dsn_sep = qr/(?<!\\),/;
399+
400 eval {
401 require DBI;
402 };
403@@ -1190,7 +1192,8 @@
404 my %final_props;
405 my $opts = $self->{opts};
406
407- foreach my $dsn_part ( split(/,/, $dsn) ) {
408+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
409+ $dsn_part =~ s/\\,/,/g;
410 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
411 $given_props{$prop_key} = $prop_val;
412 }
413
414=== modified file 'bin/pt-query-advisor'
415--- bin/pt-query-advisor 2012-04-03 19:42:45 +0000
416+++ bin/pt-query-advisor 2012-05-24 17:33:24 +0000
417@@ -28,6 +28,8 @@
418 $Data::Dumper::Indent = 0;
419 $Data::Dumper::Quotekeys = 0;
420
421+my $dsn_sep = qr/(?<!\\),/;
422+
423 eval {
424 require DBI;
425 };
426@@ -82,7 +84,8 @@
427 my %final_props;
428 my $opts = $self->{opts};
429
430- foreach my $dsn_part ( split(/,/, $dsn) ) {
431+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
432+ $dsn_part =~ s/\\,/,/g;
433 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
434 $given_props{$prop_key} = $prop_val;
435 }
436
437=== modified file 'bin/pt-query-digest'
438--- bin/pt-query-digest 2012-05-23 22:07:05 +0000
439+++ bin/pt-query-digest 2012-05-24 17:33:24 +0000
440@@ -28,6 +28,8 @@
441 $Data::Dumper::Indent = 0;
442 $Data::Dumper::Quotekeys = 0;
443
444+my $dsn_sep = qr/(?<!\\),/;
445+
446 eval {
447 require DBI;
448 };
449@@ -82,7 +84,8 @@
450 my %final_props;
451 my $opts = $self->{opts};
452
453- foreach my $dsn_part ( split(/,/, $dsn) ) {
454+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
455+ $dsn_part =~ s/\\,/,/g;
456 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
457 $given_props{$prop_key} = $prop_val;
458 }
459@@ -141,12 +144,14 @@
460 sub as_string {
461 my ( $self, $dsn, $props ) = @_;
462 return $dsn unless ref $dsn;
463- my %allowed = $props ? map { $_=>1 } @$props : ();
464+ my @keys = $props ? @$props : sort keys %$dsn;
465 return join(',',
466- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
467- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
468- grep { !$props || $allowed{$_} }
469- sort keys %$dsn );
470+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
471+ grep {
472+ exists $self->{opts}->{$_}
473+ && exists $dsn->{$_}
474+ && defined $dsn->{$_}
475+ } @keys);
476 }
477
478 sub usage {
479
480=== modified file 'bin/pt-show-grants'
481--- bin/pt-show-grants 2012-04-03 19:42:45 +0000
482+++ bin/pt-show-grants 2012-05-24 17:33:24 +0000
483@@ -1053,6 +1053,8 @@
484 $Data::Dumper::Indent = 0;
485 $Data::Dumper::Quotekeys = 0;
486
487+my $dsn_sep = qr/(?<!\\),/;
488+
489 eval {
490 require DBI;
491 };
492@@ -1107,7 +1109,8 @@
493 my %final_props;
494 my $opts = $self->{opts};
495
496- foreach my $dsn_part ( split(/,/, $dsn) ) {
497+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
498+ $dsn_part =~ s/\\,/,/g;
499 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
500 $given_props{$prop_key} = $prop_val;
501 }
502@@ -1166,12 +1169,14 @@
503 sub as_string {
504 my ( $self, $dsn, $props ) = @_;
505 return $dsn unless ref $dsn;
506- my %allowed = $props ? map { $_=>1 } @$props : ();
507+ my @keys = $props ? @$props : sort keys %$dsn;
508 return join(',',
509- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
510- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
511- grep { !$props || $allowed{$_} }
512- sort keys %$dsn );
513+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
514+ grep {
515+ exists $self->{opts}->{$_}
516+ && exists $dsn->{$_}
517+ && defined $dsn->{$_}
518+ } @keys);
519 }
520
521 sub usage {
522
523=== modified file 'bin/pt-slave-delay'
524--- bin/pt-slave-delay 2012-04-03 19:42:45 +0000
525+++ bin/pt-slave-delay 2012-05-24 17:33:24 +0000
526@@ -1136,6 +1136,8 @@
527 $Data::Dumper::Indent = 0;
528 $Data::Dumper::Quotekeys = 0;
529
530+my $dsn_sep = qr/(?<!\\),/;
531+
532 eval {
533 require DBI;
534 };
535@@ -1190,7 +1192,8 @@
536 my %final_props;
537 my $opts = $self->{opts};
538
539- foreach my $dsn_part ( split(/,/, $dsn) ) {
540+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
541+ $dsn_part =~ s/\\,/,/g;
542 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
543 $given_props{$prop_key} = $prop_val;
544 }
545@@ -1249,12 +1252,14 @@
546 sub as_string {
547 my ( $self, $dsn, $props ) = @_;
548 return $dsn unless ref $dsn;
549- my %allowed = $props ? map { $_=>1 } @$props : ();
550+ my @keys = $props ? @$props : sort keys %$dsn;
551 return join(',',
552- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
553- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
554- grep { !$props || $allowed{$_} }
555- sort keys %$dsn );
556+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
557+ grep {
558+ exists $self->{opts}->{$_}
559+ && exists $dsn->{$_}
560+ && defined $dsn->{$_}
561+ } @keys);
562 }
563
564 sub usage {
565
566=== modified file 'bin/pt-slave-find'
567--- bin/pt-slave-find 2012-05-17 14:54:36 +0000
568+++ bin/pt-slave-find 2012-05-24 17:33:24 +0000
569@@ -1053,6 +1053,8 @@
570 $Data::Dumper::Indent = 0;
571 $Data::Dumper::Quotekeys = 0;
572
573+my $dsn_sep = qr/(?<!\\),/;
574+
575 eval {
576 require DBI;
577 };
578@@ -1107,7 +1109,8 @@
579 my %final_props;
580 my $opts = $self->{opts};
581
582- foreach my $dsn_part ( split(/,/, $dsn) ) {
583+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
584+ $dsn_part =~ s/\\,/,/g;
585 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
586 $given_props{$prop_key} = $prop_val;
587 }
588@@ -1166,12 +1169,14 @@
589 sub as_string {
590 my ( $self, $dsn, $props ) = @_;
591 return $dsn unless ref $dsn;
592- my %allowed = $props ? map { $_=>1 } @$props : ();
593+ my @keys = $props ? @$props : sort keys %$dsn;
594 return join(',',
595- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
596- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
597- grep { !$props || $allowed{$_} }
598- sort keys %$dsn );
599+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
600+ grep {
601+ exists $self->{opts}->{$_}
602+ && exists $dsn->{$_}
603+ && defined $dsn->{$_}
604+ } @keys);
605 }
606
607 sub usage {
608
609=== modified file 'bin/pt-slave-restart'
610--- bin/pt-slave-restart 2012-05-17 14:54:36 +0000
611+++ bin/pt-slave-restart 2012-05-24 17:33:24 +0000
612@@ -1213,6 +1213,8 @@
613 $Data::Dumper::Indent = 0;
614 $Data::Dumper::Quotekeys = 0;
615
616+my $dsn_sep = qr/(?<!\\),/;
617+
618 eval {
619 require DBI;
620 };
621@@ -1267,7 +1269,8 @@
622 my %final_props;
623 my $opts = $self->{opts};
624
625- foreach my $dsn_part ( split(/,/, $dsn) ) {
626+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
627+ $dsn_part =~ s/\\,/,/g;
628 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
629 $given_props{$prop_key} = $prop_val;
630 }
631@@ -1326,12 +1329,14 @@
632 sub as_string {
633 my ( $self, $dsn, $props ) = @_;
634 return $dsn unless ref $dsn;
635- my %allowed = $props ? map { $_=>1 } @$props : ();
636+ my @keys = $props ? @$props : sort keys %$dsn;
637 return join(',',
638- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
639- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
640- grep { !$props || $allowed{$_} }
641- sort keys %$dsn );
642+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
643+ grep {
644+ exists $self->{opts}->{$_}
645+ && exists $dsn->{$_}
646+ && defined $dsn->{$_}
647+ } @keys);
648 }
649
650 sub usage {
651
652=== modified file 'bin/pt-table-checksum'
653--- bin/pt-table-checksum 2012-05-18 15:05:43 +0000
654+++ bin/pt-table-checksum 2012-05-24 17:33:24 +0000
655@@ -28,6 +28,8 @@
656 $Data::Dumper::Indent = 0;
657 $Data::Dumper::Quotekeys = 0;
658
659+my $dsn_sep = qr/(?<!\\),/;
660+
661 eval {
662 require DBI;
663 };
664@@ -82,7 +84,8 @@
665 my %final_props;
666 my $opts = $self->{opts};
667
668- foreach my $dsn_part ( split(/,/, $dsn) ) {
669+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
670+ $dsn_part =~ s/\\,/,/g;
671 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
672 $given_props{$prop_key} = $prop_val;
673 }
674
675=== modified file 'bin/pt-table-sync'
676--- bin/pt-table-sync 2012-05-22 17:47:24 +0000
677+++ bin/pt-table-sync 2012-05-24 17:33:24 +0000
678@@ -1172,6 +1172,8 @@
679 $Data::Dumper::Indent = 0;
680 $Data::Dumper::Quotekeys = 0;
681
682+my $dsn_sep = qr/(?<!\\),/;
683+
684 eval {
685 require DBI;
686 };
687@@ -1226,7 +1228,8 @@
688 my %final_props;
689 my $opts = $self->{opts};
690
691- foreach my $dsn_part ( split(/,/, $dsn) ) {
692+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
693+ $dsn_part =~ s/\\,/,/g;
694 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
695 $given_props{$prop_key} = $prop_val;
696 }
697
698=== modified file 'bin/pt-table-usage'
699--- bin/pt-table-usage 2012-04-03 19:42:45 +0000
700+++ bin/pt-table-usage 2012-05-24 17:33:24 +0000
701@@ -28,6 +28,8 @@
702 $Data::Dumper::Indent = 0;
703 $Data::Dumper::Quotekeys = 0;
704
705+my $dsn_sep = qr/(?<!\\),/;
706+
707 eval {
708 require DBI;
709 };
710@@ -82,7 +84,8 @@
711 my %final_props;
712 my $opts = $self->{opts};
713
714- foreach my $dsn_part ( split(/,/, $dsn) ) {
715+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
716+ $dsn_part =~ s/\\,/,/g;
717 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
718 $given_props{$prop_key} = $prop_val;
719 }
720
721=== modified file 'bin/pt-upgrade'
722--- bin/pt-upgrade 2012-04-03 19:42:45 +0000
723+++ bin/pt-upgrade 2012-05-24 17:33:24 +0000
724@@ -28,6 +28,8 @@
725 $Data::Dumper::Indent = 0;
726 $Data::Dumper::Quotekeys = 0;
727
728+my $dsn_sep = qr/(?<!\\),/;
729+
730 eval {
731 require DBI;
732 };
733@@ -82,7 +84,8 @@
734 my %final_props;
735 my $opts = $self->{opts};
736
737- foreach my $dsn_part ( split(/,/, $dsn) ) {
738+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
739+ $dsn_part =~ s/\\,/,/g;
740 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
741 $given_props{$prop_key} = $prop_val;
742 }
743
744=== modified file 'bin/pt-variable-advisor'
745--- bin/pt-variable-advisor 2012-04-03 19:42:45 +0000
746+++ bin/pt-variable-advisor 2012-05-24 17:33:24 +0000
747@@ -1053,6 +1053,8 @@
748 $Data::Dumper::Indent = 0;
749 $Data::Dumper::Quotekeys = 0;
750
751+my $dsn_sep = qr/(?<!\\),/;
752+
753 eval {
754 require DBI;
755 };
756@@ -1107,7 +1109,8 @@
757 my %final_props;
758 my $opts = $self->{opts};
759
760- foreach my $dsn_part ( split(/,/, $dsn) ) {
761+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
762+ $dsn_part =~ s/\\,/,/g;
763 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
764 $given_props{$prop_key} = $prop_val;
765 }
766@@ -1166,12 +1169,14 @@
767 sub as_string {
768 my ( $self, $dsn, $props ) = @_;
769 return $dsn unless ref $dsn;
770- my %allowed = $props ? map { $_=>1 } @$props : ();
771+ my @keys = $props ? @$props : sort keys %$dsn;
772 return join(',',
773- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
774- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
775- grep { !$props || $allowed{$_} }
776- sort keys %$dsn );
777+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
778+ grep {
779+ exists $self->{opts}->{$_}
780+ && exists $dsn->{$_}
781+ && defined $dsn->{$_}
782+ } @keys);
783 }
784
785 sub usage {
786
787=== modified file 'bin/pt-visual-explain'
788--- bin/pt-visual-explain 2012-04-03 19:42:45 +0000
789+++ bin/pt-visual-explain 2012-05-24 17:33:24 +0000
790@@ -1725,6 +1725,8 @@
791 $Data::Dumper::Indent = 0;
792 $Data::Dumper::Quotekeys = 0;
793
794+my $dsn_sep = qr/(?<!\\),/;
795+
796 eval {
797 require DBI;
798 };
799@@ -1779,7 +1781,8 @@
800 my %final_props;
801 my $opts = $self->{opts};
802
803- foreach my $dsn_part ( split(/,/, $dsn) ) {
804+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
805+ $dsn_part =~ s/\\,/,/g;
806 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
807 $given_props{$prop_key} = $prop_val;
808 }
809@@ -1838,12 +1841,14 @@
810 sub as_string {
811 my ( $self, $dsn, $props ) = @_;
812 return $dsn unless ref $dsn;
813- my %allowed = $props ? map { $_=>1 } @$props : ();
814+ my @keys = $props ? @$props : sort keys %$dsn;
815 return join(',',
816- map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
817- grep { defined $dsn->{$_} && $self->{opts}->{$_} }
818- grep { !$props || $allowed{$_} }
819- sort keys %$dsn );
820+ map { "$_=" . ($_ eq 'p' ? '...' : $dsn->{$_}) }
821+ grep {
822+ exists $self->{opts}->{$_}
823+ && exists $dsn->{$_}
824+ && defined $dsn->{$_}
825+ } @keys);
826 }
827
828 sub usage {
829
830=== modified file 'docs/percona-toolkit.pod'
831--- docs/percona-toolkit.pod 2012-04-03 19:42:45 +0000
832+++ docs/percona-toolkit.pod 2012-05-24 17:33:24 +0000
833@@ -313,6 +313,20 @@
834 key part. For example, if DSN C<h=host1> and option C<--port=12345> are
835 specified, then the tool automatically adds C<P=12345> to DSN.
836
837+=head2 ESCAPING VALUES
838+
839+DSNs are usually specified on the command line, so shell quoting and escaping
840+must be taken into account. Special characters, like asterisk (C<*>), need
841+to be quoted and/or escaped properly to be passed as literal characters in
842+DSN values.
843+
844+Since DSN parts are separated by commas, literal commas in DSN values must
845+be escaped with a single backslash (C<\>). And since a backslash is
846+the escape character for most shells, two backslashes are required to pass
847+a literal backslash. For example, if the username is literally C<my,name>,
848+it must be specified as C<my\\,name> on most shells. This applies to DSNs
849+and DSN-related options like C<--user>.
850+
851 =head2 KEY PARTS
852
853 Many of the tools add more parts to DSNs for special purposes, and sometimes
854
855=== modified file 'lib/DSNParser.pm'
856--- lib/DSNParser.pm 2012-01-19 19:46:56 +0000
857+++ lib/DSNParser.pm 2012-05-24 17:33:24 +0000
858@@ -32,6 +32,10 @@
859 $Data::Dumper::Indent = 0;
860 $Data::Dumper::Quotekeys = 0;
861
862+# Passwords may contain commas.
863+# https://bugs.launchpad.net/percona-toolkit/+bug/886077
864+my $dsn_sep = qr/(?<!\\),/;
865+
866 eval {
867 require DBI;
868 };
869@@ -126,7 +130,8 @@
870 my $opts = $self->{opts};
871
872 # Parse given props
873- foreach my $dsn_part ( split(/,/, $dsn) ) {
874+ foreach my $dsn_part ( split($dsn_sep, $dsn) ) {
875+ $dsn_part =~ s/\\,/,/g;
876 if ( my ($prop_key, $prop_val) = $dsn_part =~ m/^(.)=(.*)$/ ) {
877 # Handle the typical DSN parts like h=host, P=3306, etc.
878 $given_props{$prop_key} = $prop_val;
879
880=== modified file 't/lib/DSNParser.t'
881--- t/lib/DSNParser.t 2012-03-06 13:56:08 +0000
882+++ t/lib/DSNParser.t 2012-05-24 17:33:24 +0000
883@@ -9,12 +9,14 @@
884 use strict;
885 use warnings FATAL => 'all';
886 use English qw(-no_match_vars);
887-use Test::More tests => 27;
888+use Test::More tests => 35;
889
890 use DSNParser;
891 use OptionParser;
892 use PerconaTest;
893
894+use Data::Dumper;
895+
896 my $opts = [
897 {
898 key => 'A',
899@@ -83,6 +85,20 @@
900 );
901
902 is_deeply(
903+ $dp->parse('S=/tmp/sock'),
904+ { u => undef,
905+ p => undef,
906+ S => '/tmp/sock',
907+ h => undef,
908+ P => undef,
909+ F => undef,
910+ D => undef,
911+ A => undef,
912+ },
913+ 'Basic DSN with one part'
914+);
915+
916+is_deeply(
917 $dp->parse('u=a,p=b,A=utf8'),
918 { u => 'a',
919 p => 'b',
920@@ -392,6 +408,8 @@
921 'Copy DSN and overwrite destination'
922 );
923
924+pop @$opts; # Remove t part.
925+
926 # #############################################################################
927 # Issue 93: DBI error messages can include full SQL
928 # #############################################################################
929@@ -462,6 +480,67 @@
930 };
931
932 # #############################################################################
933+# Passwords with commas don't work, expose part of password
934+# https://bugs.launchpad.net/percona-toolkit/+bug/886077
935+# #############################################################################
936+
937+sub test_password_comma {
938+ my ($dsn_string, $pass, $port, $name) = @_;
939+ my $dsn = $dp->parse($dsn_string);
940+ is_deeply(
941+ $dsn,
942+ { u => 'a',
943+ p => $pass,
944+ S => undef,
945+ h => undef,
946+ P => $port,
947+ F => undef,
948+ D => undef,
949+ A => undef,
950+ },
951+ "$name (bug 886077)"
952+ ) or diag(Dumper($dsn));
953+}
954+
955+my @password_commas = (
956+ ['u=a,p=foo\,xxx,P=12345', 'foo,xxx', 12345, 'Pass with comma'],
957+ ['u=a,p=foo\,xxx', 'foo,xxx', undef, 'Pass with comma, last part'],
958+ ['u=a,p=foo\,,P=12345', 'foo,', 12345, 'Pass ends with comma'],
959+ ['u=a,p=foo\,', 'foo,', undef, 'Pass ends with comma, last part'],
960+ ['u=a,p=\,,P=12345', ',', 12345, 'Pass is a comma'],
961+);
962+foreach my $password_comma ( @password_commas ) {
963+ test_password_comma(@$password_comma);
964+}
965+
966+sub test_password_comma_with_auto {
967+ my ($dsn_string, $pass, $port, $name) = @_;
968+ my $dsn = $dp->parse($dsn_string);
969+ is_deeply(
970+ $dsn,
971+ { u => undef,
972+ p => $pass,
973+ S => undef,
974+ h => 'host',
975+ P => $port,
976+ F => undef,
977+ D => undef,
978+ A => undef,
979+ },
980+ "$name (bug 886077)"
981+ ) or diag(Dumper($dsn));
982+}
983+
984+@password_commas = (
985+ ['host,p=a\,z,P=9', 'a,z', 9, 'Comma-pass with leading bareword host'],
986+ ['p=a\,z,P=9,host', 'a,z', 9, 'Comma-pass with trailing bareword host'],
987+
988+);
989+foreach my $password_comma ( @password_commas ) {
990+ test_password_comma_with_auto(@$password_comma);
991+}
992+
993+# #############################################################################
994 # Done.
995 # #############################################################################
996 $dbh->disconnect() if $dbh;

Subscribers

People subscribed via source and target branches