download corrupted with IPv6 #290

Closed
opened 2026-10-04 23:50:48 +02:00 by adam · 4 comments
Owner

Reported by palleroy0 on 16 Nov 2014 05:58

Version: 2.7.1

When using the "Download this file" link while viewing a picture, every jpeg file was being corrupted. The beginning of the jpeg file contained the text "<pre></pre>" causing the corruption. I was able to track this to the file functions_mysqli.inc.php line 829-831 and functions_mysql.inc.php lines 758-760. In my specific circumstance, I use IPv6. When accessing my site through IPv6, I recieve this error "PHP Warning: [mysql error 1406] Data too long for column 'IP' at row 1\n\nINSERT INTO piwigo_history\n (\n date, \n time,\n user_id,\n IP,\n section,\n category_id,\n image_id,\n image_type,\n tag_ids\n )\n VALUES\n (\n CURRENT_DATE,\n CURRENT_TIME,\n 2,\n '_Removed IPv6 address_',\n NULL,\n NULL,\n 3077,\n 'high',\n NULL\n )\n; in /piwigo/include/dblayer/functions_mysqli.inc.php on line 830"

This error was causing the previously mentioned lines of code to print the tags "<pre></pre>". When using the download link, the tags are being printed to the beginning of the jpeg file causing corruption of the jpeg.

Steps to reproduce: Have an mysql error when the "Download this file" link is used. In my case, the mysql error was the fact that an IPv6 address is too long for the IP field in piwigo_history in the mysql database. The lines of code in functions_mysqli.inc.php line 829-831 and functions_mysql.inc.php lines 758-760 print the tags "<pre></pre>" to the beginning of the jpeg file.

Piwigo Bugtracker #3176

**Reported by palleroy0 on 16 Nov 2014 05:58** **Version:** 2.7.1 When using the &quot;Download this file&quot; link while viewing a picture, every jpeg file was being corrupted. The beginning of the jpeg file contained the text &quot;&lt;pre&gt;&lt;/pre&gt;&quot; causing the corruption. I was able to track this to the file functions_mysqli.inc.php line 829-831 and functions_mysql.inc.php lines 758-760. In my specific circumstance, I use IPv6. When accessing my site through IPv6, I recieve this error &quot;PHP Warning: [mysql error 1406] Data too long for column &#039;IP&#039; at row 1\n\nINSERT INTO piwigo_history\n (\n date, \n time,\n user_id,\n IP,\n section,\n category_id,\n image_id,\n image_type,\n tag_ids\n )\n VALUES\n (\n CURRENT_DATE,\n CURRENT_TIME,\n 2,\n &#039;**_Removed IPv6 address**_&#039;,\n NULL,\n NULL,\n 3077,\n &#039;high&#039;,\n NULL\n )\n; in /piwigo/include/dblayer/functions_mysqli.inc.php on line 830&quot; This error was causing the previously mentioned lines of code to print the tags &quot;&lt;pre&gt;&lt;/pre&gt;&quot;. When using the download link, the tags are being printed to the beginning of the jpeg file causing corruption of the jpeg. **Steps to reproduce:** Have an mysql error when the &quot;Download this file&quot; link is used. In my case, the mysql error was the fact that an IPv6 address is too long for the IP field in piwigo_history in the mysql database. The lines of code in functions_mysqli.inc.php line 829-831 and functions_mysql.inc.php lines 758-760 print the tags &quot;&lt;pre&gt;&lt;/pre&gt;&quot; to the beginning of the jpeg file. [Piwigo Bugtracker #3176](http://piwigo.org/bugs/view.php?id=3176) <!-- github-sync-id:97226973 -->
adam closed this issue 2026-10-04 23:50:48 +02:00
Author
Owner

Comment posted by palleroy0 on 16 Nov 2014 06:07

Instances of the text <pre></pre> disappeared from the report.

**Comment posted by palleroy0 on 16 Nov 2014 06:07** Instances of the text &lt;pre&gt;&lt;/pre&gt; disappeared from the report. <!-- github-comment-id:124899087 -->
Author
Owner

Comment posted by palleroy0 on 16 Nov 2014 06:08

Instances of the text < pre > < / pre > disappeared form the report.

**Comment posted by palleroy0 on 16 Nov 2014 06:08** Instances of the text &lt; pre &gt; &lt; / pre &gt; disappeared form the report. <!-- github-comment-id:124899100 -->
Author
Owner

An IPv6 can be up to 45 chars long. Let's say piwigo_history.IP colum should be enlarged from 15 to 50 chars.

I have some test on : alter table history change IP IP char(50) NOT NULL default '';

On Piwigo.org/demo it took 262 seconds (~4.5 minutes) for 43 millions lines (=> ~6s/million). That's a lot of lines but that's not uncommon at all. 4 minutes is awfully long. I'm afraid we will have to find another way to solve this problem.

Older versions of MySQL have no problem with that, because they truncate the string during insert. We can do the same in PHP. OK that's not great but IPv6 is very uncommon and we have other "problems" with IPv6 (see functions_session). We will "fix" them a better way in the future.

So let's say we truncate the string, which part is the most "unique", beginning or ending?

An IPv6 can be up to 45 chars long. Let's say piwigo_history.IP colum should be enlarged from 15 to 50 chars. I have some test on : alter table history change IP IP char(50) NOT NULL default ''; On Piwigo.org/demo it took 262 seconds (~4.5 minutes) for 43 millions lines (=> ~6s/million). That's a lot of lines but that's not uncommon at all. 4 minutes is awfully long. I'm afraid we will have to find another way to solve this problem. Older versions of MySQL have no problem with that, because they truncate the string during insert. We can do the same in PHP. OK that's not great but IPv6 is very uncommon and we have other "problems" with IPv6 (see functions_session). We will "fix" them a better way in the future. So let's say we truncate the string, which part is the most "unique", beginning or ending? <!-- github-comment-id:184289451 -->
Author
Owner
mysql> select version();
+-------------------------+
| version()               |
+-------------------------+
| 5.1.61-0ubuntu0.10.04.1 |
+-------------------------+
1 row in set (0.00 sec)

mysql> create table history2 (ip varchar(15) not null default '');
Query OK, 0 rows affected (0.11 sec)

mysql> insert into history2 set ip='2001:0db8:0000:85a3:0000:0000:ac1f:8001';
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from history2;
+-----------------+
| ip              |
+-----------------+
| 2001:0db8:0000: |
+-----------------+
1 row in set (0.00 sec)

So, to keep the same behavior, we should simply do:


if (strpos($ip,':') !== false and strlen($ip) > 15)
{
  $ip = substr($ip, 0, 15);
}
``` mysql> select version(); +-------------------------+ | version() | +-------------------------+ | 5.1.61-0ubuntu0.10.04.1 | +-------------------------+ 1 row in set (0.00 sec) mysql> create table history2 (ip varchar(15) not null default ''); Query OK, 0 rows affected (0.11 sec) mysql> insert into history2 set ip='2001:0db8:0000:85a3:0000:0000:ac1f:8001'; Query OK, 1 row affected, 1 warning (0.00 sec) mysql> select * from history2; +-----------------+ | ip | +-----------------+ | 2001:0db8:0000: | +-----------------+ 1 row in set (0.00 sec) ``` So, to keep the same behavior, we should simply do: ``` if (strpos($ip,':') !== false and strlen($ip) > 15) { $ip = substr($ip, 0, 15); } ``` <!-- github-comment-id:184298149 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/Piwigo#290