php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50363 Invalid parsing in convert.quoted-printable-decode filter
Submitted: 2009-12-02 20:17 UTC Modified: 2011-05-25 01:50 UTC
Votes:4
Avg. Score:4.8 ± 0.4
Reproduced:4 of 4 (100.0%)
Same Version:4 (100.0%)
Same OS:3 (75.0%)
From: slusarz at curecanti dot org Assigned: felipe (profile)
Status: Closed Package: Streams related
PHP Version: 5.*, 6 OS: *
Private report: No CVE-ID: None
 [2009-12-02 20:17 UTC] slusarz at curecanti dot org
Description:
------------
Using the quoted-printable-decode filter on a stream produces an error.  However, decoding the string using quoted_printable_decode() does not fail.

The error is thrown whether stream_filter_append() is used or a while !feof()/fwrite()/fread() loop is used.

Reproduce code:
---------------
$a = fopen('php://temp', 'r+');
fwrite($a, "SERVER: [ID job :3453 Backup rotation] Sauvegarde r=c3=a9ussi(e)");
rewind($a);

$b = fopen('php://temp', 'r+');
$c = stream_filter_append($b, 'convert.quoted-printable-decode', STREAM_FILTER_WRITE);
stream_copy_to_stream($a, $b);
rewind($b);
fpassthru($b);
stream_filter_remove($c);

rewind($a);
rewind($b);
fwrite($b, quoted_printable_decode(stream_get_contents($a)));
rewind($b);
fpassthru($b);


Expected result:
----------------
SERVER: [ID job :3453 Backup rotation] Sauvegarde réussi(e)
SERVER: [ID job :3453 Backup rotation] Sauvegarde réussi(e)

Actual result:
--------------
PHP Warning:  stream_copy_to_stream(): stream filter (convert.quoted-printable-decode): invalid byte sequence in /tmp/test.php on line 8
SERVER: [ID job :3453 Backup rotation] Sauvegarde réussi(e)

Patches

QP_Patch (last revision 2010-04-29 23:00 UTC by slusarz at curecanti dot org)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-12-02 22:39 UTC] jani@php.net
We have (if I counted right) 3 different implementations for encoding/decoding quoted-printable. And unfortunately filters.c has the buggy one which requires the encoded hex chars be upper-case, since this works:

<?php

$foo = "Sauvegarder=C3=A9ussi(e)";
// $foo = "Sauvegarder=c3=a9ussi(e)"; // Does not work!
$b = fopen('php://temp', 'w+');
stream_filter_append($b, 'convert.quoted-printable-decode', STREAM_FILTER_WRITE);
fwrite($b, $foo);
rewind($b);
fpassthru($b);

?>

 [2010-02-05 22:00 UTC] slusarz at curecanti dot org
Here's a patch that works for me. (Doesn't deal with the issue of the duplicative q-p code in PHP, but at least in makes the filtering code work with lowercase hex).

--- filters.c.old       2010-02-05 14:56:57.536943283 -0700
+++ filters.c   2010-02-05 14:51:11.353644566 -0700
@@ -1051,18 +1051,17 @@
                        } /* break is missing intentionally */

                        case 2: {
-                               unsigned int nbl;
-
                                if (icnt <= 0) {
                                        goto out;
                                }
-                               nbl = (*ps >= 'A' ? *ps - 0x37 : *ps - 0x30);

-                               if (nbl > 15) {
+                               if (!isxdigit((int) *ps)) {
                                        err = PHP_CONV_ERR_INVALID_SEQ;
                                        goto out;
-                               }
-                               next_char = (next_char << 4) | nbl;
+                               }
+
+                               next_char = (next_char << 4) | (*ps >= 'A' ? *ps - 0x37 : *ps - 0x30);

                                scan_stat++;
                                ps++, icnt--;
 [2011-05-25 01:49 UTC] felipe@php.net
Automatic comment from SVN on behalf of felipe
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=311407
Log: - Fixed bug #50363 (Invalid parsing in convert.quoted-printable-decode filter)
  Patch by: slusarz at curecanti dot org
 [2011-05-25 01:50 UTC] felipe@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: felipe
 [2011-05-25 01:50 UTC] felipe@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Thanks for the patch! :)
 [2012-04-18 09:50 UTC] laruence@php.net
Automatic comment on behalf of felipe
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b2780241d7354d9282a88e6bc615eb8b13e2af59
Log: - Fixed bug #50363 (Invalid parsing in convert.quoted-printable-decode filter)   Patch by: slusarz at curecanti dot org
 [2012-07-24 23:41 UTC] rasmus@php.net
Automatic comment on behalf of felipe
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b2780241d7354d9282a88e6bc615eb8b13e2af59
Log: - Fixed bug #50363 (Invalid parsing in convert.quoted-printable-decode filter)   Patch by: slusarz at curecanti dot org
 [2013-11-17 09:38 UTC] laruence@php.net
Automatic comment on behalf of felipe
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b2780241d7354d9282a88e6bc615eb8b13e2af59
Log: - Fixed bug #50363 (Invalid parsing in convert.quoted-printable-decode filter)   Patch by: slusarz at curecanti dot org
 [2019-05-22 08:00 UTC] lserni at gmail dot com
There apparently is a 8K buffer somewhere in the stream decoder (I'm looking at an obsolete PHP 5.3 now); on hitting exactly the sweet spot (I suspect an off-by-one boundary error), a valid quoted-printable sequence
 
es:Cert><xades:CertDigest><ds:DigestMethod Algorithm=3D"http://www.w3.org/2=
001/04/xmlenc#sha256"/><ds:DigestValue>IoxqxvKlcid+Ul8y6xoggwfld+T1sTaesRXv=
Y8sqO1o=3D</ds:DigestValue></xades:CertDigest><xades:IssuerSerialV2>MIGOMIG=
BpH8wfTELMAkGA1UEBhMCSVQxJDAiBgNVBAoMG05hbWlyaWFsIFMucC5BLi8wMjA0NjU3MDQyNj=
EgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxJjAkBgNVBAMMHU5hbWlyaWFsIENBI=
EZpcm1hIFF1YWxpZmljYXRhAgh4ZkpnSDVI6A=3D=3D</xades:IssuerSerialV2></xades:C=
ert></xades:SigningCertificateV2></xades:SignedSignatureProperties><xades:S=
ignedDataObjectProperties><xades:DataObjectFormat ObjectReference=3D"#null"=
><xades:MimeType>application/octet-stream</xades:MimeType></xades:DataObjec=
tFormat></xades:SignedDataObjectProperties></xades:SignedProperties></xades=

gets an extra LF added, resulting in

....</xades:C
ert>....

(which then becomes "</xades:C ert>", which is invalid XML. That's how I noticed it).
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 05:01:29 2024 UTC