Skip to content

Commit 6bba22c

Browse files
akolarjulieqiu
authored andcommitted
internal/frontend: replace \r\n with \n in readmes and licences
Replace CRLF line terminators in readme and license files before rendering Overview and Licenses tabs on the Details page. Keeping \r characters interferes with blackfriday's parser, resulting in an incorrectly rendered HTML output (see golang/go#40203 for details). Fixes golang/go#40203. Change-Id: Id6c2951c9f23e7054957071cf1c33fd3fa6494c6 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/243457 Reviewed-by: Julie Qiu <[email protected]>
1 parent 8cba941 commit 6bba22c

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

internal/frontend/license.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package frontend
66

77
import (
8+
"bytes"
89
"context"
910
"sort"
1011
"strconv"
@@ -63,6 +64,7 @@ func transformLicenses(modulePath, requestedVersion string, dbLicenses []*licens
6364
}
6465
anchors := licenseAnchors(filePaths)
6566
for i, l := range dbLicenses {
67+
l.Contents = bytes.ReplaceAll(l.Contents, []byte("\r"), nil)
6668
licenses[i] = License{
6769
Anchor: anchors[i],
6870
License: l,

internal/frontend/license_test.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
package frontend
66

77
import (
8+
"bytes"
89
"context"
910
"sort"
11+
"strings"
1012
"testing"
1113

1214
"github.com/google/go-cmp/cmp"
13-
"github.com/google/go-cmp/cmp/cmpopts"
1415
"github.com/google/safehtml"
1516
"golang.org/x/pkgsite/internal/licenses"
1617
"golang.org/x/pkgsite/internal/postgres"
1718
"golang.org/x/pkgsite/internal/stdlib"
1819
"golang.org/x/pkgsite/internal/testing/sample"
20+
"golang.org/x/pkgsite/internal/testing/testhelper"
1921
)
2022

2123
func TestLicenseAnchors(t *testing.T) {
@@ -43,12 +45,27 @@ func TestLicenseAnchors(t *testing.T) {
4345
func TestFetchLicensesDetails(t *testing.T) {
4446
testModule := sample.Module(sample.ModulePath, "v1.2.3", "A/B")
4547
stdlibModule := sample.Module(stdlib.ModulePath, "v1.13.0", "cmd/go")
48+
crlfPath := "github.com/crlf/module_name"
49+
crlfModule := sample.Module(crlfPath, "v1.2.3", "A")
50+
4651
mit := &licenses.Metadata{Types: []string{"MIT"}, FilePath: "LICENSE"}
4752
bsd := &licenses.Metadata{Types: []string{"BSD-3-Clause"}, FilePath: "A/B/LICENSE"}
4853

49-
mitLicense := &licenses.License{Metadata: mit}
50-
bsdLicense := &licenses.License{Metadata: bsd}
54+
mitLicense := &licenses.License{
55+
Metadata: mit,
56+
Contents: []byte(testhelper.MITLicense),
57+
}
58+
mitLicenseCRLF := &licenses.License{
59+
Metadata: mit,
60+
Contents: []byte(strings.ReplaceAll(testhelper.MITLicense, "\n", "\r\n")),
61+
}
62+
bsdLicense := &licenses.License{
63+
Metadata: bsd,
64+
Contents: []byte(testhelper.BSD0License),
65+
}
66+
5167
testModule.Licenses = []*licenses.License{bsdLicense, mitLicense}
68+
crlfModule.Licenses = []*licenses.License{mitLicenseCRLF}
5269
sort.Slice(testModule.Directories, func(i, j int) bool {
5370
return testModule.Directories[i].Path < testModule.Directories[j].Path
5471
})
@@ -68,6 +85,9 @@ func TestFetchLicensesDetails(t *testing.T) {
6885
if err := testDB.InsertModule(ctx, stdlibModule); err != nil {
6986
t.Fatal(err)
7087
}
88+
if err := testDB.InsertModule(ctx, crlfModule); err != nil {
89+
t.Fatal(err)
90+
}
7191
for _, test := range []struct {
7292
err error
7393
name, fullPath, modulePath, version string
@@ -115,6 +135,13 @@ func TestFetchLicensesDetails(t *testing.T) {
115135
version: stdlibModule.Version,
116136
want: stdlibModule.Licenses,
117137
},
138+
{
139+
name: "module with CRLF line terminators",
140+
fullPath: crlfPath,
141+
modulePath: crlfPath,
142+
version: crlfModule.Version,
143+
want: crlfModule.Licenses,
144+
},
118145
} {
119146
t.Run(test.name, func(t *testing.T) {
120147
wantDetails := &LicensesDetails{Licenses: transformLicenses(
@@ -124,11 +151,15 @@ func TestFetchLicensesDetails(t *testing.T) {
124151
t.Fatal(err)
125152
}
126153
if diff := cmp.Diff(wantDetails, got,
127-
cmpopts.IgnoreFields(licenses.License{}, "Contents"),
128154
cmp.AllowUnexported(safehtml.HTML{}, safehtml.Identifier{}),
129155
); diff != "" {
130156
t.Errorf("mismatch (-want +got):\n%s", diff)
131157
}
158+
for _, l := range got.Licenses {
159+
if bytes.Contains(l.Contents, []byte("\r")) {
160+
t.Errorf("license %s contains \\r line terminators", l.Metadata.FilePath)
161+
}
162+
}
132163
})
133164
}
134165
}

internal/frontend/overview.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ func ReadmeHTML(ctx context.Context, mi *internal.ModuleInfo, readme *internal.R
145145
// Render HTML similar to blackfriday.Run(), but here we implement a custom
146146
// Walk function in order to modify image paths in the rendered HTML.
147147
b := &bytes.Buffer{}
148-
rootNode := parser.Parse([]byte(readme.Contents))
148+
contents := bytes.ReplaceAll([]byte(readme.Contents), []byte("\r"), nil)
149+
rootNode := parser.Parse(contents)
149150
var walkErr error
150151
rootNode.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
151152
switch node.Type {

internal/frontend/overview_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,21 @@ func TestReadmeHTML(t *testing.T) {
192192
"<p>It’s part of a demonstration of\n" +
193193
`<a href="https://research.swtch.com/vgo1" rel="nofollow">package versioning in Go</a>.</p>`,
194194
},
195+
{
196+
name: "valid markdown readme with CRLF",
197+
mi: &internal.ModuleInfo{},
198+
readme: &internal.Readme{
199+
Filepath: "README.md",
200+
Contents: "This package collects pithy sayings.\r\n\r\n" +
201+
"- It's part of a demonstration of\r\n" +
202+
"- [package versioning in Go](https://research.swtch.com/vgo1).",
203+
},
204+
want: "<p>This package collects pithy sayings.</p>\n\n" +
205+
"<ul>\n" +
206+
"<li>It’s part of a demonstration of</li>\n" +
207+
`<li><a href="https://research.swtch.com/vgo1" rel="nofollow">package versioning in Go</a>.</li>` + "\n" +
208+
"</ul>\n",
209+
},
195210
{
196211
name: "not markdown readme",
197212
mi: &internal.ModuleInfo{},

0 commit comments

Comments
 (0)