# [PATCH] gitweb: Convert Content-Disposition filenames into qtext

10 messages from 2006-10-06 to 2006-10-07. Participants: Luben Tuikov, Petr Baudis, Jakub Narebski, Junio C Hamano.
Thread: https://gitlist.dev/t/5840

## Luben Tuikov, 2006-10-06 19:18

Subject: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <20061006191801.68649.qmail@web31815.mail.mud.yahoo.com>
URL: https://gitlist.dev/e/20061006191801.68649.qmail%40web31815.mail.mud.yahoo.com

```
Convert a string (e.g. a filename) into qtext as defined
in RFC 822, from RFC 2183.  To be used by Content-Disposition.

Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
---
 gitweb/gitweb.perl |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)


diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f848648..a35d02c 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -520,6 +520,16 @@ sub esc_html {
 	return $str;
 }
 
+# Convert a string (e.g. a filename) into qtext as defined
+# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
+sub to_qtext {
+	my $str = shift;
+	$str =~ s/\\/\\\\/g;
+	$str =~ s/\"/\\\"/g;
+	$str =~ s/\r/\\r/g;
+	return $str;
+}
+
 # git may return quoted and escaped filenames
 sub unquote {
 	my $str = shift;
@@ -2742,7 +2752,7 @@ sub git_blob_plain {
 	print $cgi->header(
 		-type => "$type",
 		-expires=>$expires,
-		-content_disposition => 'inline; filename="' . "$save_as" . '"');
+		-content_disposition => 'inline; filename="' . to_qtext("$save_as") . '"');
 	undef $/;
 	binmode STDOUT, ':raw';
 	print <$fd>;
@@ -2917,7 +2927,7 @@ sub git_snapshot {
 	print $cgi->header(
 		-type => 'application/x-tar',
 		-content_encoding => $ctype,
-		-content_disposition => 'inline; filename="' . "$filename" . '"',
+		-content_disposition => 'inline; filename="' . to_qtext("$filename") . '"',
 		-status => '200 OK');
 
 	my $git = git_cmd_str();
@@ -3224,7 +3234,7 @@ sub git_blobdiff {
 			-type => 'text/plain',
 			-charset => 'utf-8',
 			-expires => $expires,
-			-content_disposition => 'inline; filename="' . "$file_name" . '.patch"');
+			-content_disposition => 'inline; filename="' . to_qtext("$file_name") . '.patch"');
 
 		print "X-Git-Url: " . $cgi->self_url() . "\n\n";
 
@@ -3327,7 +3337,7 @@ sub git_commitdiff {
 			-type => 'text/plain',
 			-charset => 'utf-8',
 			-expires => $expires,
-			-content_disposition => 'inline; filename="' . "$filename" . '"');
+			-content_disposition => 'inline; filename="' . to_qtext("$filename") . '"');
 		my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
 		print <<TEXT;
 From: $co{'author'}
-- 
1.4.2.3.g0954


```

## Petr Baudis, 2006-10-06 19:20

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <20061006192006.GW20017@pasky.or.cz>
URL: https://gitlist.dev/e/20061006192006.GW20017%40pasky.or.cz
In-Reply-To: <20061006191801.68649.qmail@web31815.mail.mud.yahoo.com>

```
Dear diary, on Fri, Oct 06, 2006 at 09:18:01PM CEST, I got a letter
where Luben Tuikov <ltuikov@yahoo.com> said that...
> Convert a string (e.g. a filename) into qtext as defined
> in RFC 822, from RFC 2183.  To be used by Content-Disposition.
> 
> Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
> ---
>  gitweb/gitweb.perl |   18 ++++++++++++++----
>  1 files changed, 14 insertions(+), 4 deletions(-)

Content-Description: 1207600725-p1.txt
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index f848648..a35d02c 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -520,6 +520,16 @@ sub esc_html {
>  	return $str;
>  }
>  
> +# Convert a string (e.g. a filename) into qtext as defined
> +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
> +sub to_qtext {
> +	my $str = shift;
> +	$str =~ s/\\/\\\\/g;
> +	$str =~ s/\"/\\\"/g;
> +	$str =~ s/\r/\\r/g;

\r? Not \n?

> +	return $str;
> +}
> +
>  # git may return quoted and escaped filenames
>  sub unquote {
>  	my $str = shift;

Other than that,

Acked-by: Petr Baudis <pasky@suse.cz>

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

```

## Luben Tuikov, 2006-10-06 19:30

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <20061006193059.21334.qmail@web31807.mail.mud.yahoo.com>
URL: https://gitlist.dev/e/20061006193059.21334.qmail%40web31807.mail.mud.yahoo.com
In-Reply-To: <20061006192006.GW20017@pasky.or.cz>

```
--- Petr Baudis <pasky@suse.cz> wrote:
> Dear diary, on Fri, Oct 06, 2006 at 09:18:01PM CEST, I got a letter
> where Luben Tuikov <ltuikov@yahoo.com> said that...
> > Convert a string (e.g. a filename) into qtext as defined
> > in RFC 822, from RFC 2183.  To be used by Content-Disposition.
> > 
> > Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
> > ---
> >  gitweb/gitweb.perl |   18 ++++++++++++++----
> >  1 files changed, 14 insertions(+), 4 deletions(-)
> 
> Content-Description: 1207600725-p1.txt
> > diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> > index f848648..a35d02c 100755
> > --- a/gitweb/gitweb.perl
> > +++ b/gitweb/gitweb.perl
> > @@ -520,6 +520,16 @@ sub esc_html {
> >  	return $str;
> >  }
> >  
> > +# Convert a string (e.g. a filename) into qtext as defined
> > +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
> > +sub to_qtext {
> > +	my $str = shift;
> > +	$str =~ s/\\/\\\\/g;
> > +	$str =~ s/\"/\\\"/g;
> > +	$str =~ s/\r/\\r/g;
> 
> \r? Not \n?

Yes, \r, not \n.

\n is LF, \r is CR, from ASCII(7).

LF is legal in qtext as defined in RFC 822.
The illegals in qtext are CR, backslash and double quote.

   Luben

> 
> > +	return $str;
> > +}
> > +
> >  # git may return quoted and escaped filenames
> >  sub unquote {
> >  	my $str = shift;
> 
> Other than that,
> 
> Acked-by: Petr Baudis <pasky@suse.cz>
> 
> -- 
> 				Petr "Pasky" Baudis
> Stuff: http://pasky.or.cz/
> #!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
> $/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
> lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
> 

```

## Jakub Narebski, 2006-10-07 09:05

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <eg7qj5$d7d$1@sea.gmane.org>
URL: https://gitlist.dev/e/eg7qj5%24d7d%241%40sea.gmane.org
In-Reply-To: <20061006191801.68649.qmail@web31815.mail.mud.yahoo.com>

```
Luben Tuikov wrote:

> +# Convert a string (e.g. a filename) into qtext as defined
> +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
> +sub to_qtext {
> +       my $str = shift;
> +       $str =~ s/\\/\\\\/g;
> +       $str =~ s/\"/\\\"/g;
> +       $str =~ s/\r/\\r/g;
> +       return $str;
> +}

I'd rather add \n too.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```

## Junio C Hamano, 2006-10-07 09:46

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <7vk63ctq47.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vk63ctq47.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <20061006193059.21334.qmail@web31807.mail.mud.yahoo.com>

```
Luben Tuikov <ltuikov@yahoo.com> writes:

>> > +# Convert a string (e.g. a filename) into qtext as defined
>> > +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
>> > +sub to_qtext {
>> > +	my $str = shift;
>> > +	$str =~ s/\\/\\\\/g;
>> > +	$str =~ s/\"/\\\"/g;
>> > +	$str =~ s/\r/\\r/g;
>> 
>> \r? Not \n?
>
> Yes, \r, not \n.

\r to \\r? Not to \\\r?

```

## Jakub Narebski, 2006-10-07 10:06

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <eg7u5n$mt9$1@sea.gmane.org>
URL: https://gitlist.dev/e/eg7u5n%24mt9%241%40sea.gmane.org
In-Reply-To: <7vk63ctq47.fsf@assigned-by-dhcp.cox.net>

```
Junio C Hamano wrote:

> Luben Tuikov <ltuikov@yahoo.com> writes:
> 
>>>> +# Convert a string (e.g. a filename) into qtext as defined
>>>> +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
>>>> +sub to_qtext {
>>>> +  my $str = shift;
>>>> +  $str =~ s/\\/\\\\/g;
>>>> +  $str =~ s/\"/\\\"/g;

Here probably it could be
        $str =~ s/"/\\"/g;

>>>> +  $str =~ s/\r/\\r/g;
>>> 
>>> \r? Not \n?
>>
>> Yes, \r, not \n.
> 
> \r to \\r? Not to \\\r?

We want "\r" in suggested filename, not "\
" I think, so it is "\\r".

Otherwise we could use simplier
        $str =~ s/([\\"\r])/\\\1/g;

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```

## Junio C Hamano, 2006-10-07 10:34

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <7vvemwqusl.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vvemwqusl.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <eg7u5n$mt9$1@sea.gmane.org>

```
Jakub Narebski <jnareb@gmail.com> writes:

> Junio C Hamano wrote:
>
>> Luben Tuikov <ltuikov@yahoo.com> writes:
>> 
>>>>> +# Convert a string (e.g. a filename) into qtext as defined
>>>>> +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
>>>>> +sub to_qtext {
>>>>> +  my $str = shift;
>>>>> +  $str =~ s/\\/\\\\/g;
>>>>> +  $str =~ s/\"/\\\"/g;
>
> Here probably it could be
>         $str =~ s/"/\\"/g;
>
>>>>> +  $str =~ s/\r/\\r/g;
>>>> 
>>>> \r? Not \n?
>>>
>>> Yes, \r, not \n.
>> 
>> \r to \\r? Not to \\\r?
>
> We want "\r" in suggested filename, not "\
> " I think, so it is "\\r".

Is that what you guys are attempting to achieve?

If we are trying to suggest a filename that is safe by avoiding
certain characters, I suspect leaving a backslash and dq as-is
is just as bad as leaving a CR in.  So if that is the goal here,
I think it might be better and a lot simpler to just replace
each run of bytes not in Portable Filename Character Set with an
underscore '_'.

```

## Petr Baudis, 2006-10-07 11:46

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <20061007114602.GX20017@pasky.or.cz>
URL: https://gitlist.dev/e/20061007114602.GX20017%40pasky.or.cz
In-Reply-To: <eg7u5n$mt9$1@sea.gmane.org>

```
Dear diary, on Sat, Oct 07, 2006 at 12:06:31PM CEST, I got a letter
where Jakub Narebski <jnareb@gmail.com> said that...
> >>>> +  $str =~ s/\r/\\r/g;
> >>> 
> >>> \r? Not \n?
> >>
> >> Yes, \r, not \n.
> > 
> > \r to \\r? Not to \\\r?
> 
> We want "\r" in suggested filename, not "\
> " I think, so it is "\\r".

Oh, yes. Lubin wants. It looked sane until I've read it as you
explicitly wrote it. ;-)

That's "obviously" wrong. In qtext, \r means just r, no special
interpretation is done. So we indeed _would_ want "\
". Which is of course a nice trap for buggy browsers so in fact we
obviously do not want that. I think it's not wort the potential problems
to try to carry newlines in the header, so I would just replace that
line with

	$str =~ s/[\n\r]/_/g;

as per Junio's suggestion.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

```

## Jakub Narebski, 2006-10-07 12:11

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <eg85ga$9g6$1@sea.gmane.org>
URL: https://gitlist.dev/e/eg85ga%249g6%241%40sea.gmane.org
In-Reply-To: <20061007114602.GX20017@pasky.or.cz>

```
Petr Baudis wrote:

> Dear diary, on Sat, Oct 07, 2006 at 12:06:31PM CEST, I got a letter
> where Jakub Narebski <jnareb@gmail.com> said that...
>> >>>> +  $str =~ s/\r/\\r/g;
>> >>> 
>> >>> \r? Not \n?
>> >>
>> >> Yes, \r, not \n.
>> > 
>> > \r to \\r? Not to \\\r?
>> 
>> We want "\r" in suggested filename, not "\
>> " I think, so it is "\\r".
> 
> Oh, yes. Lubin wants. It looked sane until I've read it as you
> explicitly wrote it. ;-)
> 
> That's "obviously" wrong. In qtext, \r means just r, no special
> interpretation is done. So we indeed _would_ want "\
> ". Which is of course a nice trap for buggy browsers so in fact we
> obviously do not want that. I think it's not wort the potential problems
> to try to carry newlines in the header, so I would just replace that
> line with
> 
>       $str =~ s/[\n\r]/_/g;
> 
> as per Junio's suggestion.

Bu the way, using the following script:

-- >8 --
#!/usr/bin/perl

use strict;
use warnings;
use CGI qw(:standard :escapeHTML -nosticky);

binmode STDOUT, ':utf8';

our $cgi = new CGI;

print $cgi->header(
        -type => 'text/plain',
        -charset => 'utf-8',
        -content_disposition => 'inline; filename="test\".\\"test\\n.\\\n"');

print "TEST\n";
-- >8 --

I've checked that at least Mozilla 1.7.12 wants to using "\n"
in file name instead of literal eoln.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```

## Luben Tuikov, 2006-10-07 18:01

Subject: Re: [PATCH] gitweb: Convert Content-Disposition filenames into qtext
Message-ID: <20061007180115.59728.qmail@web31814.mail.mud.yahoo.com>
URL: https://gitlist.dev/e/20061007180115.59728.qmail%40web31814.mail.mud.yahoo.com
In-Reply-To: <7vvemwqusl.fsf@assigned-by-dhcp.cox.net>

```
--- Junio C Hamano <junkio@cox.net> wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
> 
> > Junio C Hamano wrote:
> >
> >> Luben Tuikov <ltuikov@yahoo.com> writes:
> >> 
> >>>>> +# Convert a string (e.g. a filename) into qtext as defined
> >>>>> +# in RFC 822, from RFC 2183.  To be used by Content-Disposition.
> >>>>> +sub to_qtext {
> >>>>> +  my $str = shift;
> >>>>> +  $str =~ s/\\/\\\\/g;
> >>>>> +  $str =~ s/\"/\\\"/g;
> >
> > Here probably it could be
> >         $str =~ s/"/\\"/g;
> >
> >>>>> +  $str =~ s/\r/\\r/g;
> >>>> 
> >>>> \r? Not \n?
> >>>
> >>> Yes, \r, not \n.
> >> 
> >> \r to \\r? Not to \\\r?
> >
> > We want "\r" in suggested filename, not "\
> > " I think, so it is "\\r".
> 
> Is that what you guys are attempting to achieve?

I think so.

> If we are trying to suggest a filename that is safe by avoiding
> certain characters, I suspect leaving a backslash and dq as-is
> is just as bad as leaving a CR in.  So if that is the goal here,
> I think it might be better and a lot simpler to just replace
> each run of bytes not in Portable Filename Character Set with an
> underscore '_'.

I think that if I were to download a file which had those chars
in it, I'd like to at least be able to see the _intention_ of what
chars the actual file name had.

So if I download a filename which looks like this:

     This is a \" test \" file \\.\r

Then I know that the intention had been:

     This is a " test " file \.<CR>

It becomes an intention, since it needs to be carried over
a qtext.

   Luben

```
