threads / bug / 11655

[BUG] git send-email brakes patches with very long lines

Subject: [BUG] git send-email brakes patches with very long lines

## tl;dr

24 messages between Jan 17, 2008 and Jan 21, 2008.

replies: 23people: 5as markdown or json

Adam Piatyszek· Jan 17, 2008, 10:10 UTC · lore
Hi Giters,

I suspect that "git send-email" has problems with sending patches with very long lines.

Please find the attached two emails, which show this problem. The original file (0001-Add-Dolph-Chebyshev-window.patch) was produced with "git format-patch" from one of my private Git repositories. The other file (0001-Add-Dolph-Chebyshev-window-sent.patch) includes the same patch but sent with "git send-email". The problem is with the last hunk, which is somehow broken by the "git send-email" tool. The very long lines are wrapped and some exclamation marks are inserted.

The result of applying such a broken patch in my repository is as follows:

===== >8 ===== ediap@lespaul ~/git/itpp $ git am 0001-Add-Dolph-Chebyshev-window-sent.patch Applying Add Dolph Chebyshev window. fatal: corrupt patch at line 126 Patch failed at 0001. When you have resolved this problem run "git-am --resolved". If you would prefer to skip this patch, instead run "git-am --skip". ===== >8 =====

If I send the same patch with mutt inlined or attached, the patch is not broken and applies cleanly.

This problem was observed for the following git versions:
- 1.5.3.8
- 1.5.4.rc3.4.g1633

BR, /Adam

PS. Email and IP addresses have been removed from the attached patches.
-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.


From 171043d6daec26ede0c4d6584d7a70eea214f0fe Mon Sep 17 00:00:00 2001
From: K <email@example.com>
Date: Tue, 15 Jan 2008 22:52:14 +0530
Subject: [PATCH] Add Dolph Chebyshev window.

Add the chebwin function to evaluate the coefficients of the
Dolph-Chebyshev Window, with tests.

The tests check the values output by the Dolph-Chebyshev window
function for lengths 32 and 33 for 50 dB suppression and for lengths
127 and 128 at 25 dB suppression.

Signed-off-by: K <email@example.com>
---
 itpp/signal/window.cpp |   39 ++++++++++++++++++++++++++++++++++++++-
 itpp/signal/window.h   |   18 ++++++++++++++++++
 tests/window_test.cpp  |    5 +++++
 tests/window_test.ref  |    4 ++++
 4 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/itpp/signal/window.cpp b/itpp/signal/window.cpp
index 0bf4be5..cfe27a8 100644
--- a/itpp/signal/window.cpp
+++ b/itpp/signal/window.cpp
@@ -27,7 +27,12 @@
  */
 
 #include <itpp/signal/window.h>
-
+#include <itpp/signal/poly.h>
+#include <itpp/base/specmat.h>
+#include <itpp/base/converters.h>
+#include <itpp/base/math/trig_hyp.h>
+#include <itpp/signal/transforms.h>
+#include <itpp/base/operators.h>
 
 namespace itpp {
 
@@ -106,6 +111,38 @@ namespace itpp {
     return t;
   }
 
+  vec chebwin(int n, double at)
+  {
+    it_assert((n > 0), "chebwin(): need a positive order n!");
+    if (n == 1) {
+      return vec("1");
+    }
+
+    at = at < 0 ? -at : at;
+    // compute the parameter beta
+    double beta = std::cosh(::acosh(pow10(at/20.)) / (n-1));
+    vec k = (pi / n) * linspace(0, n - 1, n);
+    vec cos_k = cos(k);
+    // find the window's DFT coefficients
+    vec p = cheb(n - 1, beta * cos_k);
+
+    // Appropriate IDFT and filling up
+    // depending on even/odd n
+    vec w; // the window vector.
+    if (is_even(n)) {
+      w = ifft_real(to_cvec(elem_mult(p, cos_k), elem_mult(p,-sin(k))));
+      int half_length = n / 2 + 1;
+      w = w / w(1);
+      w = concat(reverse(w.left(half_length)), w.mid(2, half_length - 2));
+    }
+    else {
+      w = ifft_real(to_cvec(p));
+      int half_length = (n + 1) / 2;
+      w = w.left(half_length) / w(0);
+      w = concat(reverse(w), w.right(half_length - 1));
+    }
+    return w;
+  }
 
 
 } // namespace itpp
diff --git a/itpp/signal/window.h b/itpp/signal/window.h
index aad510f..12f5205 100644
--- a/itpp/signal/window.h
+++ b/itpp/signal/window.h
@@ -105,6 +105,24 @@ namespace itpp {
   sqrt_win(n) = sqrt(triang(n))
   */
   vec sqrt_win(int n);
+
+  /*! \brief Dolph-Chebyshev Window
+
+
+  The length \c n Dolph-Chebyshev window is a vector \f$w\f$ whose \f$i\f$th
+  transform component is given by
+  \f[
+  W[k] = \frac{T_M\left(\beta \cos\left(\frac{\pi k}{M}\right)
+  \right)}{T_M(\beta)},k = 0, 1, 2, \ldots, M - 1
+  \f]
+
+  where \c T_n(x) is the order \c n Chebyshev polynomial of the first kind.
+  \param n Length of the Doplh-Chebyshev window.
+  \param at Attenutation of side lobe (in dB).
+  \return Symmetric length \c n Doplh-Chebyshev window.
+  \author
+  */
+  vec chebwin(int n, double at);
   //!@}
 
 
diff --git a/tests/window_test.cpp b/tests/window_test.cpp
index 31fcff5..6d3fb15 100644
--- a/tests/window_test.cpp
+++ b/tests/window_test.cpp
@@ -56,5 +56,10 @@ int main(void)
   cout << "triang(32) = " << round_to_zero(triang(32)) << endl;
   cout << "triang(128) = " << round_to_zero(triang(128)) << endl;
 
+  cout << "chebwin(32) = " << round_to_zero(chebwin(32, 50)) << endl;
+  cout << "chebwin(33) = " << round_to_zero(chebwin(33, 20)) << endl;
+  cout << "chebwin(127) = " << round_to_zero(chebwin(127, 25)) << endl;
+  cout << "chebwin(128) = " << round_to_zero(chebwin(128, 25)) << endl;
+
   return 0;
 }
diff --git a/tests/window_test.ref b/tests/window_test.ref
index 7b1793c..e988967 100644
--- a/tests/window_test.ref
+++ b/tests/window_test.ref
@@ -11,3 +11,7 @@ blackman(32) = [0 0.0037516543 0.015638448 0.0374027 0.071464607 0.12028646 0.18
 blackman(128) = [0 0.00022048463 0.00088426938 0.0019983131 0.0035741016 0.0056274806 0.008178424 0.011250741 0.014871722 0.019071735 0.023883764 0.029342905 0.035485826 0.042350182 0.049974012 0.058395105 0.067650362 0.077775135 0.08880258 0.100763 0.11368324 0.12758601 0.14248936 0.15840611 0.17534333 0.19330184 0.21227586 0.23225262 0.25321203 0.27512651 0.29796076 0.32167173 0.34620856 0.37151262 0.3975177 0.42415015 0.45132921 0.47896731 0.50697053 0.53523907 0.56366781 0.59214691 0.62056245 0.64879721 0.67673135 0.70424322 0.73121023 0.7575096 0.7830193 0.80761885 0.83119025 0.85361875 0.87479376 0.89460963 0.91296646 0.9297708 0.94493641 0.95838489 0.97004626 0.97985951 0.98777306 0.99374518 0.99774428 0.99974914 0.99974914 0.99774428 0.99374518 0.98777306 0.97985951 0.97004626 0.95838489 0.94493641 0.9297708 0.91296646 0.89460963 0.87479376 0.85361875 0.83119025 0.80761885 0.7830193 0.7575096 0.73121023 0.70424322 0.67673135 0.64879721 0.62056245 0.59214691 0.56366781 0.53523907 0.50697053 0.47896731 0.45132921 0.42415015 0.3975177 0.37151262 0.34620856 0.32167173 0.29796076 0.27512651 0.25321203 0.23225262 0.21227586 0.19330184 0.17534333 0.15840611 0.14248936 0.12758601 0.11368324 0.100763 0.08880258 0.077775135 0.067650362 0.058395105 0.049974012 0.042350182 0.035485826 0.029342905 0.023883764 0.019071735 0.014871722 0.011250741 0.008178424 0.0056274806 0.0035741016 0.0019983131 0.00088426938 0.00022048463 0]
 triang(32) = [0.03125 0.09375 0.15625 0.21875 0.28125 0.34375 0.40625 0.46875 0.53125 0.59375 0.65625 0.71875 0.78125 0.84375 0.90625 0.96875 0.96875 0.90625 0.84375 0.78125 0.71875 0.65625 0.59375 0.53125 0.46875 0.40625 0.34375 0.28125 0.21875 0.15625 0.09375 0.03125]
 triang(128) = [0.0078125 0.0234375 0.0390625 0.0546875 0.0703125 0.0859375 0.1015625 0.1171875 0.1328125 0.1484375 0.1640625 0.1796875 0.1953125 0.2109375 0.2265625 0.2421875 0.2578125 0.2734375 0.2890625 0.3046875 0.3203125 0.3359375 0.3515625 0.3671875 0.3828125 0.3984375 0.4140625 0.4296875 0.4453125 0.4609375 0.4765625 0.4921875 0.5078125 0.5234375 0.5390625 0.5546875 0.5703125 0.5859375 0.6015625 0.6171875 0.6328125 0.6484375 0.6640625 0.6796875 0.6953125 0.7109375 0.7265625 0.7421875 0.7578125 0.7734375 0.7890625 0.8046875 0.8203125 0.8359375 0.8515625 0.8671875 0.8828125 0.8984375 0.9140625 0.9296875 0.9453125 0.9609375 0.9765625 0.9921875 0.9921875 0.9765625 0.9609375 0.9453125 0.9296875 0.9140625 0.8984375 0.8828125 0.8671875 0.8515625 0.8359375 0.8203125 0.8046875 0.7890625 0.7734375 0.7578125 0.7421875 0.7265625 0.7109375 0.6953125 0.6796875 0.6640625 0.6484375 0.6328125 0.6171875 0.6015625 0.5859375 0.5703125 0.5546875 0.5390625 0.5234375 0.5078125 0.4921875 0.4765625 0.4609375 0.4453125 0.4296875 0.4140625 0.3984375 0.3828125 0.3671875 0.3515625 0.3359375 0.3203125 0.3046875 0.2890625 0.2734375 0.2578125 0.2421875 0.2265625 0.2109375 0.1953125 0.1796875 0.1640625 0.1484375 0.1328125 0.1171875 0.1015625 0.0859375 0.0703125 0.0546875 0.0390625 0.0234375 0.0078125]
+chebwin(32) = [0.050664426 0.066069435 0.10497972 0.15478981 0.21565675 0.28701938 0.36753634 0.45508472 0.5468251 0.63933249 0.72878615 0.81120512 0.88271105 0.93979671 0.97957695 1 1 0.97957695 0.93979671 0.88271105 0.81120512 0.72878615 0.63933249 0.5468251 0.45508472 0.36753634 0.28701938 0.21565675 0.15478981 0.10497972 0.066069435 0.050664426]
+chebwin(33) = [1.5667761 0.436121 0.4911289 0.5465011 0.60155649 0.65559419 0.70790584 0.75778846 0.80455735 0.84755887 0.8861828 0.91987396 0.94814295 0.97057557 0.98684093 0.99669794 1 0.99669794 0.98684093 0.97057557 0.94814295 0.91987396 0.8861828 0.84755887 0.80455735 0.75778846 0.70790584 0.65559419 0.60155649 0.5465011 0.4911289 0.436121 1.5667761]
+chebwin(127) = [2.8062784 0.28379647 0.29780485 0.31203524 0.32647609 0.34111535 0.3559405 0.37093856 0.38609612 0.40139932 0.41683391 0.43238525 0.44803833 0.46377779 0.47958794 0.49545281 0.51135612 0.52728135 0.54321176 0.55913036 0.57502004 0.59086348 0.60664326 0.62234187 0.63794169 0.65342508 0.66877439 0.68397195 0.69900016 0.71384147 0.72847843 0.7428937 0.75707013 0.77099071 0.78463866 0.79799743 0.81105075 0.82378262 0.83617737 0.84821968 0.85989459 0.87118755 0.88208441 0.89257149 0.90263557 0.91226391 0.9214443 0.93016505 0.93841505 0.94618372 0.95346113 0.9602379 0.96650532 0.97225529 0.9774804 0.98217387 0.98632963 0.98994228 0.99300712 0.99552018 0.99747819 0.99887858 0.99971955 1 0.99971955 0.99887858 0.99747819 0.99552018 0.99300712 0.98994228 0.98632963 0.98217387 0.9774804 0.97225529 0.96650532 0.9602379 0.95346113 0.94618372 0.93841505 0.93016505 0.9214443 0.91226391 0.90263557 0.89257149 0.88208441 0.87118755 0.85989459 0.84821968 0.83617737 0.82378262 0.81105075 0.79799743 0.78463866 0.77099071 0.75707013 0.7428937 0.72847843 0.71384147 0.69900016 0.68397195 0.66877439 0.65342508 0.63794169 0.62234187 0.60664326 0.59086348 0.57502004 0.55913036 0.54321176 0.52728135 0.51135612 0.49545281 0.47958794 0.46377779 0.44803833 0.43238525 0.41683391 0.40139932 0.38609612 0.37093856 0.3559405 0.34111535 0.32647609 0.31203524 0.29780485 0.28379647 2.8062784]
+chebwin(128) = [2.8276135 0.28370485 0.29760123 0.31171632 0.32603887 0.34055711 0.35525884 0.37013139 0.38516169 0.40033623 0.41564112 0.43106209 0.4465845 0.46219339 0.47787346 0.49360915 0.50938459 0.52518367 0.54099005 0.55678721 0.57255843 0.58828682 0.6039554 0.61954706 0.63504462 0.65043087 0.66568854 0.68080039 0.69574922 0.71051786 0.72508926 0.73944646 0.75357265 0.76745118 0.78106561 0.79439972 0.80743754 0.82016335 0.83256177 0.84461773 0.85631651 0.86764377 0.87858557 0.88912838 0.89925915 0.90896528 0.91823465 0.92705566 0.93541726 0.94330891 0.95072067 0.95764316 0.96406763 0.96998592 0.97539051 0.98027451 0.9846317 0.98845652 0.99174407 0.99449016 0.99669127 0.99834457 0.99944796 1 1 0.99944796 0.99834457 0.99669127 0.99449016 0.99174407 0.98845652 0.9846317 0.98027451 0.97539051 0.96998592 0.96406763 0.95764316 0.95072067 0.94330891 0.93541726 0.92705566 0.91823465 0.90896528 0.89925915 0.88912838 0.87858557 0.86764377 0.85631651 0.84461773 0.83256177 0.82016335 0.80743754 0.79439972 0.78106561 0.76745118 0.75357265 0.73944646 0.72508926 0.71051786 0.69574922 0.68080039 0.66568854 0.65043087 0.63504462 0.61954706 0.6039554 0.58828682 0.57255843 0.55678721 0.54099005 0.52518367 0.50938459 0.49360915 0.47787346 0.46219339 0.4465845 0.43106209 0.41564112 0.40033623 0.38516169 0.37013139 0.35525884 0.34055711 0.32603887 0.31171632 0.29760123 0.28370485 2.8276135]
-- 
1.5.4.rc3.4.g1633



From ediap@users.sourceforge.net Thu Jan 17 10:20:44 2008
From: =?utf-8?q?Adam=20Pi=C4=85tyszek?= <ediap@users.sourceforge.net>
To: ediap@Example.Com
Cc: K <email@example.com>
Subject: [PATCH] Add Dolph Chebyshev window.
Date: Thu, 17 Jan 2008 10:09:20 +0100
Message-Id: <1200560960-696-1-git-send-email-ediap@users.sourceforge.net>
X-Mailer: git-send-email 1.5.4.rc3.4.g1633
Status: RO
Content-Length: 10365
Lines: 136

From: K <email@example.com>

Add the chebwin function to evaluate the coefficients of the
Dolph-Chebyshev Window, with tests.

The tests check the values output by the Dolph-Chebyshev window
function for lengths 32 and 33 for 50 dB suppression and for lengths
127 and 128 at 25 dB suppression.

Signed-off-by: K <email@example.com>
---
 itpp/signal/window.cpp |   39 ++++++++++++++++++++++++++++++++++++++-
 itpp/signal/window.h   |   18 ++++++++++++++++++
 tests/window_test.cpp  |    5 +++++
 tests/window_test.ref  |    4 ++++
 4 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/itpp/signal/window.cpp b/itpp/signal/window.cpp
index 0bf4be5..cfe27a8 100644
--- a/itpp/signal/window.cpp
+++ b/itpp/signal/window.cpp
@@ -27,7 +27,12 @@
  */
 
 #include <itpp/signal/window.h>
-
+#include <itpp/signal/poly.h>
+#include <itpp/base/specmat.h>
+#include <itpp/base/converters.h>
+#include <itpp/base/math/trig_hyp.h>
+#include <itpp/signal/transforms.h>
+#include <itpp/base/operators.h>
 
 namespace itpp {
 
@@ -106,6 +111,38 @@ namespace itpp {
     return t;
   }
 
+  vec chebwin(int n, double at)
+  {
+    it_assert((n > 0), "chebwin(): need a positive order n!");
+    if (n == 1) {
+      return vec("1");
+    }
+
+    at = at < 0 ? -at : at;
+    // compute the parameter beta
+    double beta = std::cosh(::acosh(pow10(at/20.)) / (n-1));
+    vec k = (pi / n) * linspace(0, n - 1, n);
+    vec cos_k = cos(k);
+    // find the window's DFT coefficients
+    vec p = cheb(n - 1, beta * cos_k);
+
+    // Appropriate IDFT and filling up
+    // depending on even/odd n
+    vec w; // the window vector.
+    if (is_even(n)) {
+      w = ifft_real(to_cvec(elem_mult(p, cos_k), elem_mult(p,-sin(k))));
+      int half_length = n / 2 + 1;
+      w = w / w(1);
+      w = concat(reverse(w.left(half_length)), w.mid(2, half_length - 2));
+    }
+    else {
+      w = ifft_real(to_cvec(p));
+      int half_length = (n + 1) / 2;
+      w = w.left(half_length) / w(0);
+      w = concat(reverse(w), w.right(half_length - 1));
+    }
+    return w;
+  }
 
 
 } // namespace itpp
diff --git a/itpp/signal/window.h b/itpp/signal/window.h
index aad510f..12f5205 100644
--- a/itpp/signal/window.h
+++ b/itpp/signal/window.h
@@ -105,6 +105,24 @@ namespace itpp {
   sqrt_win(n) = sqrt(triang(n))
   */
   vec sqrt_win(int n);
+
+  /*! \brief Dolph-Chebyshev Window
+
+
+  The length \c n Dolph-Chebyshev window is a vector \f$w\f$ whose \f$i\f$th
+  transform component is given by
+  \f[
+  W[k] = \frac{T_M\left(\beta \cos\left(\frac{\pi k}{M}\right)
+  \right)}{T_M(\beta)},k = 0, 1, 2, \ldots, M - 1
+  \f]
+
+  where \c T_n(x) is the order \c n Chebyshev polynomial of the first kind.
+  \param n Length of the Doplh-Chebyshev window.
+  \param at Attenutation of side lobe (in dB).
+  \return Symmetric length \c n Doplh-Chebyshev window.
+  \author
+  */
+  vec chebwin(int n, double at);
   //!@}
 
 
diff --git a/tests/window_test.cpp b/tests/window_test.cpp
index 31fcff5..6d3fb15 100644
--- a/tests/window_test.cpp
+++ b/tests/window_test.cpp
@@ -56,5 +56,10 @@ int main(void)
   cout << "triang(32) = " << round_to_zero(triang(32)) << endl;
   cout << "triang(128) = " << round_to_zero(triang(128)) << endl;
 
+  cout << "chebwin(32) = " << round_to_zero(chebwin(32, 50)) << endl;
+  cout << "chebwin(33) = " << round_to_zero(chebwin(33, 20)) << endl;
+  cout << "chebwin(127) = " << round_to_zero(chebwin(127, 25)) << endl;
+  cout << "chebwin(128) = " << round_to_zero(chebwin(128, 25)) << endl;
+
   return 0;
 }
diff --git a/tests/window_test.ref b/tests/window_test.ref
index 7b1793c..e988967 100644
--- a/tests/window_test.ref
+++ b/tests/window_test.ref
@@ -11,3 +11,7 @@ blackman(32) = [0 0.0037516543 0.015638448 0.0374027 0.071464607 0.12028646 0.18
 blackman(128) = [0 0.00022048463 0.00088426938 0.0019983131 0.0035741016 0.0056274806 0.008178424 0.011250741 0.014871722 0.019071735 0.023883764 0.029342905 0.035485826 0.042350182 0.049974012 0.058395105 0.067650362 0.077775135 0.08880258 0.100763 0.11368324 0.12758601 0.14248936 0.15840611 0.17534333 0.19330184 0.21227586 0.23225262 0.25321203 0.27512651 0.29796076 0.32167173 0.34620856 0.37151262 0.3975177 0.42415015 0.45132921 0.47896731 0.50697053 0.53523907 0.56366781 0.59214691 0.62056245 0.64879721 0.67673135 0.70424322 0.73121023 0.7575096 0.7830193 0.80761885 0.83119025 0.85361875 0.87479376 0.89460963 0.91296646 0.9297708 0.94493641 0.95838489 0.97004626 0.97985951 0.98777306 0.99374518 0.99774428 0.99974914 0.99974914 0.99774428 0.99374518 0.98777306 0.97985951 0.97004626 0.95838489 0.94493641 0.9297708 0.91296646 0.89460963 0.87479376 0.85361875 0.83119025 0.80761885 0.7830193 0.7575096 0.73121023 0.70424322 0.67673135 0.64879721 0.62056245 0.59214691 0.563667!
 81 0.53523907 0.50697053 0.47896731 0.45132921 0.42415015 0.3975177 0.37151262 0.34620856 0.32167173 0.29796076 0.27512651 0.25321203 0.23225262 0.21227586 0.19330184 0.17534333 0.15840611 0.14248936 0.12758601 0.11368324 0.100763 0.08880258 0.077775135 0.067650362 0.058395105 0.049974012 0.042350182 0.035485826 0.029342905 0.023883764 0.019071735 0.014871722 0.011250741 0.008178424 0.0056274806 0.0035741016 0.0019983131 0.00088426938 0.00022048463 0]
 triang(32) = [0.03125 0.09375 0.15625 0.21875 0.28125 0.34375 0.40625 0.46875 0.53125 0.59375 0.65625 0.71875 0.78125 0.84375 0.90625 0.96875 0.96875 0.90625 0.84375 0.78125 0.71875 0.65625 0.59375 0.53125 0.46875 0.40625 0.34375 0.28125 0.21875 0.15625 0.09375 0.03125]
 triang(128) = [0.0078125 0.0234375 0.0390625 0.0546875 0.0703125 0.0859375 0.1015625 0.1171875 0.1328125 0.1484375 0.1640625 0.1796875 0.1953125 0.2109375 0.2265625 0.2421875 0.2578125 0.2734375 0.2890625 0.3046875 0.3203125 0.3359375 0.3515625 0.3671875 0.3828125 0.3984375 0.4140625 0.4296875 0.4453125 0.4609375 0.4765625 0.4921875 0.5078125 0.5234375 0.5390625 0.5546875 0.5703125 0.5859375 0.6015625 0.6171875 0.6328125 0.6484375 0.6640625 0.6796875 0.6953125 0.7109375 0.7265625 0.7421875 0.7578125 0.7734375 0.7890625 0.8046875 0.8203125 0.8359375 0.8515625 0.8671875 0.8828125 0.8984375 0.9140625 0.9296875 0.9453125 0.9609375 0.9765625 0.9921875 0.9921875 0.9765625 0.9609375 0.9453125 0.9296875 0.9140625 0.8984375 0.8828125 0.8671875 0.8515625 0.8359375 0.8203125 0.8046875 0.7890625 0.7734375 0.7578125 0.7421875 0.7265625 0.7109375 0.6953125 0.6796875 0.6640625 0.6484375 0.6328125 0.6171875 0.6015625 0.5859375 0.5703125 0.5546875 0.5390625 0.5234375 0.5078125 0.4921875 0.4!
 765625 0.4609375 0.4453125 0.4296875 0.4140625 0.3984375 0.3828125 0.3671875 0.3515625 0.3359375 0.3203125 0.3046875 0.2890625 0.2734375 0.2578125 0.2421875 0.2265625 0.2109375 0.1953125 0.1796875 0.1640625 0.1484375 0.1328125 0.1171875 0.1015625 0.0859375 0.0703125 0.0546875 0.0390625 0.0234375 0.0078125]
+chebwin(32) = [0.050664426 0.066069435 0.10497972 0.15478981 0.21565675 0.28701938 0.36753634 0.45508472 0.5468251 0.63933249 0.72878615 0.81120512 0.88271105 0.93979671 0.97957695 1 1 0.97957695 0.93979671 0.88271105 0.81120512 0.72878615 0.63933249 0.5468251 0.45508472 0.36753634 0.28701938 0.21565675 0.15478981 0.10497972 0.066069435 0.050664426]
+chebwin(33) = [1.5667761 0.436121 0.4911289 0.5465011 0.60155649 0.65559419 0.70790584 0.75778846 0.80455735 0.84755887 0.8861828 0.91987396 0.94814295 0.97057557 0.98684093 0.99669794 1 0.99669794 0.98684093 0.97057557 0.94814295 0.91987396 0.8861828 0.84755887 0.80455735 0.75778846 0.70790584 0.65559419 0.60155649 0.5465011 0.4911289 0.436121 1.5667761]
+chebwin(127) = [2.8062784 0.28379647 0.29780485 0.31203524 0.32647609 0.34111535 0.3559405 0.37093856 0.38609612 0.40139932 0.41683391 0.43238525 0.44803833 0.46377779 0.47958794 0.49545281 0.51135612 0.52728135 0.54321176 0.55913036 0.57502004 0.59086348 0.60664326 0.62234187 0.63794169 0.65342508 0.66877439 0.68397195 0.69900016 0.71384147 0.72847843 0.7428937 0.75707013 0.77099071 0.78463866 0.79799743 0.81105075 0.82378262 0.83617737 0.84821968 0.85989459 0.87118755 0.88208441 0.89257149 0.90263557 0.91226391 0.9214443 0.93016505 0.93841505 0.94618372 0.95346113 0.9602379 0.96650532 0.97225529 0.9774804 0.98217387 0.98632963 0.98994228 0.99300712 0.99552018 0.99747819 0.99887858 0.99971955 1 0.99971955 0.99887858 0.99747819 0.99552018 0.99300712 0.98994228 0.98632963 0.98217387 0.9774804 0.97225529 0.96650532 0.9602379 0.95346113 0.94618372 0.93841505 0.93016505 0.9214443 0.91226391 0.90263557 0.89257149 0.88208441 0.87118755 0.85989459 0.84821968 0.83617737 0.82378262 !
 0.81105075 0.79799743 0.78463866 0.77099071 0.75707013 0.7428937 0.72847843 0.71384147 0.69900016 0.68397195 0.66877439 0.65342508 0.63794169 0.62234187 0.60664326 0.59086348 0.57502004 0.55913036 0.54321176 0.52728135 0.51135612 0.49545281 0.47958794 0.46377779 0.44803833 0.43238525 0.41683391 0.40139932 0.38609612 0.37093856 0.3559405 0.34111535 0.32647609 0.31203524 0.29780485 0.28379647 2.8062784]
+chebwin(128) = [2.8276135 0.28370485 0.29760123 0.31171632 0.32603887 0.34055711 0.35525884 0.37013139 0.38516169 0.40033623 0.41564112 0.43106209 0.4465845 0.46219339 0.47787346 0.49360915 0.50938459 0.52518367 0.54099005 0.55678721 0.57255843 0.58828682 0.6039554 0.61954706 0.63504462 0.65043087 0.66568854 0.68080039 0.69574922 0.71051786 0.72508926 0.73944646 0.75357265 0.76745118 0.78106561 0.79439972 0.80743754 0.82016335 0.83256177 0.84461773 0.85631651 0.86764377 0.87858557 0.88912838 0.89925915 0.90896528 0.91823465 0.92705566 0.93541726 0.94330891 0.95072067 0.95764316 0.96406763 0.96998592 0.97539051 0.98027451 0.9846317 0.98845652 0.99174407 0.99449016 0.99669127 0.99834457 0.99944796 1 1 0.99944796 0.99834457 0.99669127 0.99449016 0.99174407 0.98845652 0.9846317 0.98027451 0.97539051 0.96998592 0.96406763 0.95764316 0.95072067 0.94330891 0.93541726 0.92705566 0.91823465 0.90896528 0.89925915 0.88912838 0.87858557 0.86764377 0.85631651 0.84461773 0.83256177 0.820!
 16335 0.80743754 0.79439972 0.78106561 0.76745118 0.75357265 0.73944646 0.72508926 0.71051786 0.69574922 0.68080039 0.66568854 0.65043087 0.63504462 0.61954706 0.6039554 0.58828682 0.57255843 0.55678721 0.54099005 0.52518367 0.50938459 0.49360915 0.47787346 0.46219339 0.4465845 0.43106209 0.41564112 0.40033623 0.38516169 0.37013139 0.35525884 0.34055711 0.32603887 0.31171632 0.29760123 0.28370485 2.8276135]
-- 
1.5.4.rc3.4.g1633
Adam Piatyszek· Jan 17, 2008, 13:13 UTC · re: Adam Piatyszek · lore

Re: [BUG] git send-email brakes patches with very long lines

* Adam Piatyszek [17 I 2008 11:10]:
Show 21 quoted lines
> Please find the attached two emails, which show this problem. The 
> original file (0001-Add-Dolph-Chebyshev-window.patch) was produced with 
> "git format-patch" from one of my private Git repositories. The other 
> file (0001-Add-Dolph-Chebyshev-window-sent.patch) includes the same 
> patch but sent with "git send-email". The problem is with the last hunk, 
> which is somehow broken by the "git send-email" tool. The very long 
> lines are wrapped and some exclamation marks are inserted.
> 
> The result of applying such a broken patch in my repository is as follows:
> 
> ===== >8 =====
> ediap@lespaul ~/git/itpp $ git am 0001-Add-Dolph-Chebyshev-window-sent.patch
> Applying Add Dolph Chebyshev window.
> fatal: corrupt patch at line 126
> Patch failed at 0001.
> When you have resolved this problem run "git-am --resolved".
> If you would prefer to skip this patch, instead run "git-am --skip".
> ===== >8 =====
> 
> If I send the same patch with mutt inlined or attached, the patch is not 
> broken and applies cleanly.
Sorry for the noise! It seems that it is not a problem of "git send-email".

I have just resent this patch to myself once again, this time using mutt "bounce" function, and it resulted in the broken patch in exactly the same way.

The incorrect line wrapping with an exclamation mark is exactly at 990 column. Is there any limitation of the line size for text/plain messages?

BR, /Adam

-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.
Adam Piatyszek· Jan 17, 2008, 13:26 UTC · re: Adam Piatyszek · lore

Re: [BUG] git send-email brakes patches with very long lines

* Adam Piatyszek [17 I 2008 14:13]:
> The incorrect line wrapping with an exclamation mark is exactly at 990 
> column. Is there any limitation of the line size for text/plain messages?
Replying to myself again:
RFC2822 (Internet Message Format) states:
   2.1.1. Line Length Limits
     There are two limits that this standard places on the number of
     characters in a line. Each line of characters MUST be no more than
     998 characters, and SHOULD be no more than 78 characters, excluding
     the CRLF.
RFC2821 (Simple Mail Transfer Protocol) states:
   4.5.3.1 Size limits and minimums
   [...]
   text line
     The maximum total length of a text line including the <CRLF> is 1000
     characters (not counting the leading dot duplicated for
     transparency).  This number may be increased by the use of SMTP
     Service Extensions.

Now, the question is. Don't you think that "git send-email" should at least warn users that they are trying to send emails with patches that will be broken at the end?

BR, /Adam

-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.
Jeff King· Jan 17, 2008, 15:32 UTC · re: Adam Piatyszek · lore

Re: [BUG] git send-email brakes patches with very long lines

On Thu, Jan 17, 2008 at 02:26:48PM +0100, Adam Piatyszek wrote:
Show 13 quoted lines
> RFC2822 (Internet Message Format) states:
>
>   2.1.1. Line Length Limits
>
>     There are two limits that this standard places on the number of
>     characters in a line. Each line of characters MUST be no more than
>     998 characters, and SHOULD be no more than 78 characters, excluding
>     the CRLF.
> [...]
>
> Now, the question is. Don't you think that "git send-email" should at  
> least warn users that they are trying to send emails with patches that  
> will be broken at the end?

It could actually QP-encode the data in that case, I think. git-mailinfo appears to have code to handle the decoding.

-Peff
Adam Piątyszek· Jan 18, 2008, 07:47 UTC · re: Jeff King · lore

[PATCH] git-send-email.perl: check for lines longer than 998 characters

According to RFC2822 (Internet Message Format), each line of a message must be no more than 998 characters. This patch adds a check for the length of each body line of a message and dies if the length exceeds the limit.

Signed-off-by: Adam Piątyszek <ediap@users.sourceforge.net>
---
 git-send-email.perl |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index e47994a..6d623ea 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -748,6 +748,9 @@ foreach my $t (@files) {
 				$header_done = 1;
 			}
 		} else {
+			if (length($_) > 998) {
+				die "(msg) This message contains lines longer than 998 characters,\nwhich can not be correctly send as plain text using SMTP.\n";
+			}
 			$message .=  $_;
 			if (/^(Signed-off-by|Cc): (.*)$/i && $signed_off_cc) {
 				my $c = $2;
-- 
1.5.4.rc3.4.g1633
Johannes Sixt· Jan 18, 2008, 08:12 UTC · re: Adam Piątyszek · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Adam Piątyszek schrieb:
Show 24 quoted lines
> According to RFC2822 (Internet Message Format), each line of a message
> must be no more than 998 characters. This patch adds a check for the
> length of each body line of a message and dies if the length exceeds
> the limit.
> 
> Signed-off-by: Adam Piątyszek <ediap@users.sourceforge.net>
> ---
>  git-send-email.perl |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/git-send-email.perl b/git-send-email.perl
> index e47994a..6d623ea 100755
> --- a/git-send-email.perl
> +++ b/git-send-email.perl
> @@ -748,6 +748,9 @@ foreach my $t (@files) {
>  				$header_done = 1;
>  			}
>  		} else {
> +			if (length($_) > 998) {
> +				die "(msg) This message contains lines longer than 998 characters,\nwhich can not be correctly send as plain text using SMTP.\n";
> +			}
>  			$message .=  $_;
>  			if (/^(Signed-off-by|Cc): (.*)$/i && $signed_off_cc) {
>  				my $c = $2;

Is it good to die() in this situation? If you are sending a patch series and one patch in the middle triggers this condition, then only half of the series is sent. Maybe it would be better to warn here only, collect file names of the suspects, send the patch nevertheless, and write a summary at the end?

-- Hannes
Adam Piatyszek· Jan 18, 2008, 09:42 UTC · re: Johannes Sixt · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Hi,
* Johannes Sixt [18 I 2008 09:12]:
Show 5 quoted lines
> Is it good to die() in this situation? If you are sending a patch series
> and one patch in the middle triggers this condition, then only half of the
> series is sent. Maybe it would be better to warn here only, collect file
> names of the suspects, send the patch nevertheless, and write a summary at
> the end?

Unfortunately, my experience in perl programming is very, very limited. So, I did not prepared the final solution for this problem. ;-) The patch was intended as a startup of a discussion how to fix this issue.

IMHO it does not make much sense to send such patches nevertheless, if we are sure that they will be broken after SMTP transfer. Such a situation is similar to spamming. And sending only the ones that can be sent is not an option as well.

The proper solution would be to implement conditional encoding of such patches, e.g. quoted-printable as suggested by Peff, and warn users that some patches were send as encoded. Also an explicit option "--transfer-enc" might be added to control such a behaviour manually.

I guess, git send-email might reuse the code from this perl module: http://search.cpan.org/src/GAAS/MIME-Base64-Perl-1.00/lib/MIME/QuotedPrint/Perl.pm to implement the encoding routine.

There are although two things to implement:
1) When too long line is detected, the whole message body has to be 
encoded with QP.
2) Proper "Content-Transfer-Encoding: quoted-printable" needs to be set 
in the headers.

BTW, is "git am" or "git apply" able to decode the QP encoded message body? I guess yes, since it works with patches attached to emails as well...

Comments?

BR, /Adam

-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.
Johannes Sixt· Jan 18, 2008, 10:01 UTC · re: Adam Piatyszek · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Adam Piatyszek schrieb:
Show 8 quoted lines
> * Johannes Sixt [18 I 2008 09:12]:
>> Is it good to die() in this situation? If you are sending a patch series
>> and one patch in the middle triggers this condition, then only half of
>> the
>> series is sent. Maybe it would be better to warn here only, collect file
>> names of the suspects, send the patch nevertheless, and write a
>> summary at
>> the end?
> IMHO it does not make much sense to send such patches nevertheless, if
> we are sure that they will be broken after SMTP transfer. Such a
> situation is similar to spamming. And sending only the ones that can be
> sent is not an option as well.

You are right here. My thought was that even though the recipient gets a broken patch, he would be able to fix it up. This may be acceptable for peer-to-peer communication, but not for a development style that involves many recipients.

Then git-format-patch and log-family with --pretty=email -p could warn about these candidates-to-be-broken patches.

-- Hannes
Junio C Hamano· Jan 18, 2008, 10:08 UTC · re: Johannes Sixt · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Johannes Sixt <j.sixt@viscovery.net> writes:
Show 7 quoted lines
> You are right here. My thought was that even though the recipient gets a
> broken patch, he would be able to fix it up. This may be acceptable for
> peer-to-peer communication, but not for a development style that involves
> many recipients.
>
> Then git-format-patch and log-family with --pretty=email -p could warn
> about these candidates-to-be-broken patches.

I'd rather not, unless it is explicitly asked for by a separate command line option. Transferring over SMTP is not the only (nor even primary) use of format-patch output.

On the other hand, git-send-email _is_ all about SMTP transfer. Perhaps a loop over input files upfront to check the line length limit, and warn if there are suspiciously long lines even before sending the first piece of e-mail out, would be a reasonable approach.

Adam Piatyszek· Jan 18, 2008, 10:37 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

* Junio C Hamano [18 I 2008 11:08]:
Show 7 quoted lines
> Johannes Sixt <j.sixt@viscovery.net> writes:
>> Then git-format-patch and log-family with --pretty=email -p could warn
>> about these candidates-to-be-broken patches.
> 
> I'd rather not, unless it is explicitly asked for by a separate
> command line option.  Transferring over SMTP is not the only
> (nor even primary) use of format-patch output.
Agree.
Show 5 quoted lines
> On the other hand, git-send-email _is_ all about SMTP transfer.
> Perhaps a loop over input files upfront to check the line length
> limit, and warn if there are suspiciously long lines even before
> sending the first piece of e-mail out, would be a reasonable
> approach.
But what next? Still send the problematic patches not encoded?

In my opinion, it is more reasonable to provide an optional encoding of such patches. And only throw a warning message that some of the patches had to be encoded. Then, we would not need an extra loop over all patches.

As git-send-email _is_ all about SMTP transfer, we should be interested that the stuff we transfer is sent correctly.

/Adam
-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.
Junio C Hamano· Jan 18, 2008, 11:01 UTC · re: Adam Piatyszek · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Adam Piatyszek <ediap@users.sourceforge.net> writes:
> But what next? Still send the problematic patches not encoded?

I meant "warn and stop before sending anything". The sender can fix it up in any way he wants.

You _could_ give an option to send-email to allow it to QP and wrap without failing (perhaps with warning), but that should be explicitly asked for, as some people/list do not want MIME. On such a list, the sender may even have to go back to the tree and fix the file contents before regenerating the patches.

Jeff King· Jan 18, 2008, 14:16 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

On Fri, Jan 18, 2008 at 02:08:24AM -0800, Junio C Hamano wrote:
Show 5 quoted lines
> On the other hand, git-send-email _is_ all about SMTP transfer.
> Perhaps a loop over input files upfront to check the line length
> limit, and warn if there are suspiciously long lines even before
> sending the first piece of e-mail out, would be a reasonable
> approach.
I think that is sensible. Patch series will follow:
  1/3: send-email: detect invocation errors earlier
       This is a code cleanup in preparation for 2/3, but has
       user-friendly side effects.
  2/3: send-email: validate patches before sending anything
       The actual up front long-lines check.
  3/3: send-email: add no-validate option
       A knob for users who know something send-email doesn't.

That at least detects the situation and lets the user deal with it (by fixing the patch, or by sending it as an attachment with another MUA). Probably there should be a

  4/3: send-email: add --encoding parameter

but I am not inclined to code it, especially this late in the release freeze (though I think the first three are reasonable for v1.5.4, I am also fine if you want to put them off -- I don't see this as a common problem).

-Peff
Jeff King· Jan 18, 2008, 14:19 UTC · re: Jeff King · lore

[PATCH 1/3] send-email: detect invocation errors earlier

We never even look at the command line arguments until after we have prompted the user for some information. So running "git send-email" without arguments would prompt for "from" and "to" headers, only to then die with "No patch files specified." Instead, let's try to do as much error checking as possible before getting user input.

Signed-off-by: Jeff King <peff@peff.net>
---
 git-send-email.perl |   55 +++++++++++++++++++++++++--------------------------
 1 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index e47994a..7a86977 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -314,6 +314,33 @@ if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) {
 
 ($sender) = expand_aliases($sender) if defined $sender;
 
+# Now that all the defaults are set, process the rest of the command line
+# arguments and collect up the files that need to be processed.
+for my $f (@ARGV) {
+	if (-d $f) {
+		opendir(DH,$f)
+			or die "Failed to opendir $f: $!";
+
+		push @files, grep { -f $_ } map { +$f . "/" . $_ }
+				sort readdir(DH);
+
+	} elsif (-f $f) {
+		push @files, $f;
+
+	} else {
+		print STDERR "Skipping $f - not found.\n";
+	}
+}
+
+if (@files) {
+	unless ($quiet) {
+		print $_,"\n" for (@files);
+	}
+} else {
+	print STDERR "\nNo patch files specified!\n\n";
+	usage();
+}
+
 my $prompting = 0;
 if (!defined $sender) {
 	$sender = $repoauthor || $repocommitter;
@@ -427,34 +454,6 @@ EOT
 	@files = ($compose_filename . ".final");
 }
 
-
-# Now that all the defaults are set, process the rest of the command line
-# arguments and collect up the files that need to be processed.
-for my $f (@ARGV) {
-	if (-d $f) {
-		opendir(DH,$f)
-			or die "Failed to opendir $f: $!";
-
-		push @files, grep { -f $_ } map { +$f . "/" . $_ }
-				sort readdir(DH);
-
-	} elsif (-f $f) {
-		push @files, $f;
-
-	} else {
-		print STDERR "Skipping $f - not found.\n";
-	}
-}
-
-if (@files) {
-	unless ($quiet) {
-		print $_,"\n" for (@files);
-	}
-} else {
-	print STDERR "\nNo patch files specified!\n\n";
-	usage();
-}
-
 # Variables we set as part of the loop over files
 our ($message_id, %mail, $subject, $reply_to, $references, $message);
 
-- 
1.5.4.rc3.1128.g1826-dirty
Jeff King· Jan 18, 2008, 14:19 UTC · re: Jeff King · lore

[PATCH 2/3] send-email: validate patches before sending anything

We try to catch errors early so that we don't end up sending half of a broken patch series. Right now the only validation is checking that line-lengths are under the SMTP-mandated limit of 998.

The validation parsing is very crude (it just checks each line length without understanding the mailbox format) but should work fine for this simple check.

Signed-off-by: Jeff King <peff@peff.net>
---
 git-send-email.perl   |   17 +++++++++++++++++
 t/t9001-send-email.sh |   20 ++++++++++++++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index 7a86977..144d7d4 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -332,6 +332,11 @@ for my $f (@ARGV) {
 	}
 }
 
+foreach my $f (@files) {
+	my $error = validate_patch($f);
+	$error and die "fatal: $f: $error\nwarning: no patches were sent\n";
+}
+
 if (@files) {
 	unless ($quiet) {
 		print $_,"\n" for (@files);
@@ -837,3 +842,15 @@ sub unique_email_list(@) {
 	}
 	return @emails;
 }
+
+sub validate_patch {
+	my $fn = shift;
+	open(my $fh, '<', $fn)
+		or die "unable to open $fn: $!\n";
+	while (my $line = <$fh>) {
+		if (length($line) > 998) {
+			return "patch contains line longer than 998 characters";
+		}
+	}
+	return undef;
+}
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 659f9c7..1c41810 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -78,4 +78,24 @@ test_expect_success 'Show all headers' '
 	diff -u expected-show-all-headers actual-show-all-headers
 '
 
+z8=zzzzzzzz
+z64=$z8$z8$z8$z8$z8$z8$z8$z8
+z512=$z64$z64$z64$z64$z64$z64$z64$z64
+test_expect_success 'reject long lines' '
+	rm -f commandline &&
+	cp $patches longline.patch &&
+	echo $z512$z512 >>longline.patch &&
+	! git send-email \
+		--from="Example <nobody@example.com>" \
+		--to=nobody@example.com \
+		--smtp-server="$(pwd)/fake.sendmail" \
+		$patches longline.patch \
+		2>errors &&
+	grep longline.patch errors
+'
+
+test_expect_success 'no patch was sent' '
+	! test -e commandline
+'
+
 test_done
-- 
1.5.4.rc3.1128.g1826-dirty
Johannes Sixt· Jan 18, 2008, 15:09 UTC · re: Jeff King · lore

Re: [PATCH 2/3] send-email: validate patches before sending anything

Jeff King schrieb:
Show 7 quoted lines
> +sub validate_patch {
> +	my $fn = shift;
> +	open(my $fh, '<', $fn)
> +		or die "unable to open $fn: $!\n";
> +	while (my $line = <$fh>) {
> +		if (length($line) > 998) {
> +			return "patch contains line longer than 998 characters";
"... contains line_s_ longer than..."
-- Hannes
Jeff King· Jan 18, 2008, 19:09 UTC · re: Johannes Sixt · lore

Re: [PATCH 2/3] send-email: validate patches before sending anything

On Fri, Jan 18, 2008 at 04:09:19PM +0100, Johannes Sixt wrote:
Show 10 quoted lines
> Jeff King schrieb:
> > +sub validate_patch {
> > +	my $fn = shift;
> > +	open(my $fh, '<', $fn)
> > +		or die "unable to open $fn: $!\n";
> > +	while (my $line = <$fh>) {
> > +		if (length($line) > 998) {
> > +			return "patch contains line longer than 998 characters";
> 
> "... contains line_s_ longer than..."

I actually had that and changed it, since we know of only one such line (since we bail at that point). I think Jay's suggestion of outputting the line number is even better.

-Peff
Jay Soffian· Jan 18, 2008, 17:39 UTC · re: Jeff King · lore

Re: [PATCH 2/3] send-email: validate patches before sending anything

On 1/18/08, Jeff King <peff@peff.net> wrote:
Show 24 quoted lines
> +foreach my $f (@files) {
> +       my $error = validate_patch($f);
> +       $error and die "fatal: $f: $error\nwarning: no patches were sent\n";
> +}
> +
>  if (@files) {
>         unless ($quiet) {
>                 print $_,"\n" for (@files);
> @@ -837,3 +842,15 @@ sub unique_email_list(@) {
>         }
>         return @emails;
>  }
> +
> +sub validate_patch {
> +       my $fn = shift;
> +       open(my $fh, '<', $fn)
> +               or die "unable to open $fn: $!\n";
> +       while (my $line = <$fh>) {
> +               if (length($line) > 998) {
> +                       return "patch contains line longer than 998 characters";
> +               }
> +       }
> +       return undef;
> +}
How about offering the line number. e.g.:
return "patch line number $. is longer than 998 characters";
Show 9 quoted lines
> diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
> index 659f9c7..1c41810 100755
> --- a/t/t9001-send-email.sh
> +++ b/t/t9001-send-email.sh
> @@ -78,4 +78,24 @@ test_expect_success 'Show all headers' '
>         diff -u expected-show-all-headers actual-show-all-headers
>  '
>
> +test_expect_success 'no patch was sent' '
Shouldn't that be "no patches were sent" to match the perl output?
j.
Jeff King· Jan 18, 2008, 19:12 UTC · re: Jay Soffian · lore

Re: [PATCH 2/3] send-email: validate patches before sending anything

On Fri, Jan 18, 2008 at 12:39:45PM -0500, Jay Soffian wrote:
> > +                       return "patch contains line longer than 998 characters";
> How about offering the line number. e.g.:
> 
> return "patch line number $. is longer than 998 characters";

I think that is sensible (Junio, if you apply pre-1.5.4, can you mark it up? Otherwise I will put it in the post-1.5.4 resend).

> > +test_expect_success 'no patch was sent' '
> 
> Shouldn't that be "no patches were sent" to match the perl output?

It's purely an informational message for the test script output, so it doesn't matter.

-Peff
Jeff King· Jan 18, 2008, 14:20 UTC · re: Jeff King · lore

[PATCH 3/3] send-email: add no-validate option

Since we are now sanity-checking the contents of patches and refusing to send ones with long lines, this knob provides a way for the user to override the new behavior (if, e.g., he knows his SMTP path will handle it).

Signed-off-by: Jeff King <peff@peff.net>
---
 git-send-email.perl   |   12 +++++++++---
 t/t9001-send-email.sh |   10 ++++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index 144d7d4..39e0222 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -100,6 +100,8 @@ Options:
 
    --envelope-sender	Specify the envelope sender used to send the emails.
 
+   --no-validate	Don't perform any sanity checks on patches.
+
 EOT
 	exit(1);
 }
@@ -177,6 +179,7 @@ my ($quiet, $dry_run) = (0, 0);
 my ($thread, $chain_reply_to, $suppress_from, $signed_off_cc, $cc_cmd);
 my ($smtp_server, $smtp_server_port, $smtp_authuser, $smtp_authpass, $smtp_ssl);
 my ($identity, $aliasfiletype, @alias_files, @smtp_host_parts);
+my ($no_validate);
 
 my %config_bool_settings = (
     "thread" => [\$thread, 1],
@@ -222,6 +225,7 @@ my $rc = GetOptions("sender|from=s" => \$sender,
 		    "dry-run" => \$dry_run,
 		    "envelope-sender=s" => \$envelope_sender,
 		    "thread!" => \$thread,
+		    "no-validate" => \$no_validate,
 	 );
 
 unless ($rc) {
@@ -332,9 +336,11 @@ for my $f (@ARGV) {
 	}
 }
 
-foreach my $f (@files) {
-	my $error = validate_patch($f);
-	$error and die "fatal: $f: $error\nwarning: no patches were sent\n";
+if (!$no_validate) {
+	foreach my $f (@files) {
+		my $error = validate_patch($f);
+		$error and die "fatal: $f: $error\nwarning: no patches were sent\n";
+	}
 }
 
 if (@files) {
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 1c41810..4f6822f 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -98,4 +98,14 @@ test_expect_success 'no patch was sent' '
 	! test -e commandline
 '
 
+test_expect_success 'allow long lines with --no-validate' '
+	git send-email \
+		--from="Example <nobody@example.com>" \
+		--to=nobody@example.com \
+		--smtp-server="$(pwd)/fake.sendmail" \
+		--no-validate \
+		$patches longline.patch \
+		2>errors
+'
+
 test_done
-- 
1.5.4.rc3.1128.g1826-dirty
Junio C Hamano· Jan 18, 2008, 20:57 UTC · re: Jeff King · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Jeff King <peff@peff.net> writes:
Show 18 quoted lines
> On Fri, Jan 18, 2008 at 02:08:24AM -0800, Junio C Hamano wrote:
>
>> On the other hand, git-send-email _is_ all about SMTP transfer.
>> Perhaps a loop over input files upfront to check the line length
>> limit, and warn if there are suspiciously long lines even before
>> sending the first piece of e-mail out, would be a reasonable
>> approach.
>
> I think that is sensible. Patch series will follow:
>
>   1/3: send-email: detect invocation errors earlier
>
>        This is a code cleanup in preparation for 2/3, but has
>        user-friendly side effects.
>
>   2/3: send-email: validate patches before sending anything
>
>        The actual up front long-lines check.

I wonder what the performance implication of this approach would be, though. I am tempted to say that it would be negligible -- scanning text in Perl is fast enough.

Show 6 quoted lines
>   3/3: send-email: add no-validate option
>
>        A knob for users who know something send-email doesn't.
>
> That at least detects the situation and lets the user deal with it (by
> fixing the patch, or by sending it as an attachment with another MUA).

I suspect that taking this "Safe against SMTP line length limit" topic all the way ("all the way" is post 1.5.4, I am inclined to agree that this may be a good fix to an existing bug) would require that git-format-patch --attach to learn to apply QP on patch text to avoid producing very long lines to root-cause the issue [*1*].

[Footnote]

*1* It's actually second-to-root-cause it, because the real root cause is for the source tree to have such an insanely long line.

Jeff King· Jan 18, 2008, 21:30 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

On Fri, Jan 18, 2008 at 12:57:41PM -0800, Junio C Hamano wrote:
Show 7 quoted lines
> >   2/3: send-email: validate patches before sending anything
> >
> >        The actual up front long-lines check.
> 
> I wonder what the performance implication of this approach would
> be, though.  I am tempted to say that it would be negligible --
> scanning text in Perl is fast enough.

We now open and do one conditional per line for each file (in addition to already going through each file a separate time and doing more complex processing). Doing that over the entirety of "git log --pretty=email -p" on git.git takes about 1 second on my machine for 11402 patches. Obviously there's slightly more syscall overhead as you have to open() each patch, but I think think it is clear that the parsing overhead is negligible.

Show 6 quoted lines
> I suspect that taking this "Safe against SMTP line length limit"
> topic all the way ("all the way" is post 1.5.4, I am inclined to
> agree that this may be a good fix to an existing bug) would
> require that git-format-patch --attach to learn to apply QP on
> patch text to avoid producing very long lines to root-cause the
> issue [*1*].

Perhaps. If such things are sufficiently rare, one could simply attach the patch in their MUA. I think the most important thing is for git to at least stop and warn the user that it might not be sending something valid. But implementing N different fixes that haven't even been requested by users seems like a waste of time.

-Peff
Adam Piatyszek· Jan 20, 2008, 22:35 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

Hi,
Show 22 quoted lines
> Jeff King <peff@peff.net> writes:
>> I think that is sensible. Patch series will follow:
>>
>>   1/3: send-email: detect invocation errors earlier
>>
>>        This is a code cleanup in preparation for 2/3, but has
>>        user-friendly side effects.
>>
>>   2/3: send-email: validate patches before sending anything
>>
>>        The actual up front long-lines check.
> 
> I wonder what the performance implication of this approach would
> be, though.  I am tempted to say that it would be negligible --
> scanning text in Perl is fast enough.
> 
>>   3/3: send-email: add no-validate option
>>
>>        A knob for users who know something send-email doesn't.
>>
>> That at least detects the situation and lets the user deal with it (by
>> fixing the patch, or by sending it as an attachment with another MUA).

Thanks Peff for your patches. I was about to implement your first two, but it would take me much more time to do it in a sane way. ;-)

So:
Acked-by: Adam Piątyszek <ediap@users.sourceforge.net>
* Junio C Hamano [18 I 2008 21:57]:
Show 6 quoted lines
> I suspect that taking this "Safe against SMTP line length limit"
> topic all the way ("all the way" is post 1.5.4, I am inclined to
> agree that this may be a good fix to an existing bug) would
> require that git-format-patch --attach to learn to apply QP on
> patch text to avoid producing very long lines to root-cause the
> issue [*1*].

I support this idea. "git-format-patch --attach" is a good place to implement such an additional encoding. Of course, git-mailinfo needs to be extended with a decoding method as well.

> [Footnote]
> 
> *1* It's actually second-to-root-cause it, because the real root
> cause is for the source tree to have such an insanely long line.

I can not fully agree with this statement. You should have in mind that git is by the definition a "stupid content tracker" and should not assume any particular kind of data being processed. For instance, the reported problem with git-send-email was discovered when I tried to send a patch with some reference data of an unformatted standard output of a test program.

BR, /Adam

-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.
Jeff King· Jan 20, 2008, 22:53 UTC · re: Adam Piatyszek · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

On Sun, Jan 20, 2008 at 11:35:14PM +0100, Adam Piatyszek wrote:
> I support this idea. "git-format-patch --attach" is a good place to  
> implement such an additional encoding. Of course, git-mailinfo needs to  
> be extended with a decoding method as well.

I think mailinfo already does support qp, but I haven't tested it (see builtin-mailinfo.c:decode_q_segment).

Show 8 quoted lines
>> *1* It's actually second-to-root-cause it, because the real root
>> cause is for the source tree to have such an insanely long line.
> I can not fully agree with this statement. You should have in mind that  
> git is by the definition a "stupid content tracker" and should not assume 
> any particular kind of data being processed.
> For instance, the reported problem with git-send-email was discovered  
> when I tried to send a patch with some reference data of an unformatted  
> standard output of a test program.

I agree with you. One of the things that makes git so useful is that you can feed it any content and everything "just works".

That being said, there is often a distinction in git between 'text' that is reasonable for patches, mailing, etc, and 'binary', which is not. Both cases are handled by git, but in different ways appropriate to each. 1000-character lines are awfully long; should they perhaps be handled as binary files? The upside is that this fits them into a well-established niche within git. The downside is that the diffs aren't readable (though who is reading diffs with such long lines?) and I don't believe the conflict resolution is as simple.

-Peff
Adam Piatyszek· Jan 21, 2008, 10:21 UTC · re: Jeff King · lore

Re: [PATCH] git-send-email.perl: check for lines longer than 998 characters

* Jeff King [20 I 2008 23:53]:
Show 8 quoted lines
> On Sun, Jan 20, 2008 at 11:35:14PM +0100, Adam Piatyszek wrote:
> 
>> I support this idea. "git-format-patch --attach" is a good place to  
>> implement such an additional encoding. Of course, git-mailinfo needs to  
>> be extended with a decoding method as well.
> 
> I think mailinfo already does support qp, but I haven't tested it (see
> builtin-mailinfo.c:decode_q_segment).

You are right. I've just tested it and it works fine when "Content-Transfer-Encoding: quoted-printable" is declared in the header part of the email. So only the git-format-patch needs some extension for optional QP encoding.

BR, /Adam

-- 
.:.  Adam Piatyszek (ediap)  .:.....................................:.
.:.  ediap@users.sourceforge.net  .:................................:.

← back to recent threads