Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion api/iteration.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,16 @@ func readFileAsUTF8String(filename string) (*string, error) {
return nil, err
}

encoding, _, _ := charset.DetermineEncoding(b, mimeType)
encoding, _, certain := charset.DetermineEncoding(b, mimeType)
if !certain {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The consequence of replacing this line with if true:

--- FAIL: TestNewIteration (0.00s)
    iteration_test.go:54: Iteration content is not valid UTF-8 data: ÿþ# utf16le
    iteration_test.go:58: Expected utf16le.py to start with `# utf16le', had `ÿþ# utf16le'
    iteration_test.go:54: Iteration content is not valid UTF-8 data: þÿ# utf16be
    iteration_test.go:58: Expected utf16be.py to start with `# utf16be', had `þÿ# utf16be'
FAIL
FAIL    github.com/exercism/cli/api 0.019s

And the consequences of replacing with if false (as if I never wrote this code):

--- FAIL: TestNewIteration (0.00s)
    iteration_test.go:61: Expected long-utf8.py to end with `👍
        ', had `# The first 1024 bytes of this file need to contain only ASCII characters.
        # After the first 1024 bytes, then there should be a non-ASCII character.
        # Explanation: DetectEncoding checks the first 1024 bytes of a file.
        # If it can't determine the encoding and saw no non-ASCII characters,
        # it declares the file to have windows-1252 encoding.
        # This mangles the submitted file if it should have been UTF-8.
        # We test to make sure we use UTF-8 for such files, instead of windows-1252.

        lipsum = """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam condimentum vitae
        ipsum eget tempor. Morbi sed ex quis orci vulputate cursus quis non massa.
        Vestibulum quam nibh, elementum in justo in, venenatis tristique nisl. Morbi
        sagittis elit id velit ultricies, sed rutrum augue posuere. Donec nec nulla nec
        eros fringilla pellentesque. Duis at dictum justo. Nunc ut magna felis. Aliquam
        volutpat, lectus et molestie porttitor, est orci malesuada erat, ac pretium
        eros ligula vel erat. Nullam venenatis dui eget sapien semper lobortis. Aenean
        ac eros eget neque porta auctor in nec erat. Phasellus ac nulla ac turpis
        porttitor auctor. Etiam eget posuere diam, ac feugiat lacus. Curabitur ornare
        justo ut nulla congue, vitae posuere erat venenatis. Aliquam pulvinar eleifend
        faucibus.

        Etiam justo sem, faucibus malesuada purus a, ultrices efficitur ex.
        Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
        turpis egestas. Duis maximus dapibus mattis. Quisque sem ex, convallis eu
        ultricies posuere.
        """

        # �
        '
FAIL
FAIL    github.com/exercism/cli/api 0.021s

// We don't want to use an uncertain encoding.
// In particular, doing that may mangle UTF-8 files
// that have only ASCII in their first 1024 bytes.
// See https://github.com/exercism/cli/issues/309.
// So if we're unsure, use UTF-8 (no transformation).
s := string(b)
return &s, nil
}
decoder := encoding.NewDecoder()
decodedBytes, _, err := transform.Bytes(decoder, b)
if err != nil {
Expand Down
28 changes: 18 additions & 10 deletions api/iteration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestNewIteration(t *testing.T) {
filepath.Join(dir, "python", "leap", "lib", "three.py"),
filepath.Join(dir, "python", "leap", "utf16le.py"),
filepath.Join(dir, "python", "leap", "utf16be.py"),
filepath.Join(dir, "python", "leap", "long-utf8.py"),
}

iter, err := NewIteration(dir, files)
Expand All @@ -32,25 +33,32 @@ func TestNewIteration(t *testing.T) {
t.Errorf("Expected problem to be leap, was %s", iter.Problem)
}

if len(iter.Solution) != 5 {
t.Fatalf("Expected solution to have 3 files, had %d", len(iter.Solution))
if len(iter.Solution) != 6 {
t.Fatalf("Expected solution to have 6 files, had %d", len(iter.Solution))
}

expected := map[string]string{
"one.py": "# one",
"two.py": "# two",
filepath.Join("lib", "three.py"): "# three",
"utf16le.py": "# utf16le",
"utf16be.py": "# utf16be",
expected := map[string]struct {
prefix string
suffix string
}{
"one.py": {prefix: "# one"},
"two.py": {prefix: "# two"},
filepath.Join("lib", "three.py"): {prefix: "# three"},
"utf16le.py": {prefix: "# utf16le"},
"utf16be.py": {prefix: "# utf16be"},
"long-utf8.py": {prefix: "# The first 1024", suffix: "👍\n"},
}

for filename, code := range expected {
if !utf8.ValidString(iter.Solution[filename]) {
t.Errorf("Iteration content is not valid UTF-8 data: %s", iter.Solution[filename])
}

if !strings.HasPrefix(iter.Solution[filename], code) {
t.Errorf("Expected %s to contain `%s', had `%s'", filename, code, iter.Solution[filename])
if !strings.HasPrefix(iter.Solution[filename], code.prefix) {
t.Errorf("Expected %s to start with `%s', had `%s'", filename, code.prefix, iter.Solution[filename])
}
if !strings.HasSuffix(iter.Solution[filename], code.suffix) {
t.Errorf("Expected %s to end with `%s', had `%s'", filename, code.suffix, iter.Solution[filename])
}
}
}
Expand Down
31 changes: 31 additions & 0 deletions fixtures/iteration/python/leap/long-utf8.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# The first 1024 bytes of this file need to contain only ASCII characters.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of two minds. On the one hand, this is a test that knows a little too much about the implementation of the code it's testing (1024 bytes).

On the other hand, this is a real thing that happened and mangled my submission and someone else's, so it is not unwarranted.

# After the first 1024 bytes, then there should be a non-ASCII character.
#
# Explanation:
# We use golang.org/x/net/html/charset.DetectEncoding to guess file encoding.
# DetectEncoding checks the first 1024 bytes of a file.
# If it can't determine the encoding and saw no non-ASCII characters,
# it declares the file to have windows-1252 encoding.
# This mangles the submitted file if it should have been UTF-8.
# We test to make sure we use UTF-8 for such files, instead of windows-1252.

lipsum = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam condimentum vitae
ipsum eget tempor. Morbi sed ex quis orci vulputate cursus quis non massa.
Vestibulum quam nibh, elementum in justo in, venenatis tristique nisl. Morbi
sagittis elit id velit ultricies, sed rutrum augue posuere. Donec nec nulla nec
eros fringilla pellentesque. Duis at dictum justo. Nunc ut magna felis. Aliquam
volutpat, lectus et molestie porttitor, est orci malesuada erat, ac pretium
eros ligula vel erat. Nullam venenatis dui eget sapien semper lobortis. Aenean
ac eros eget neque porta auctor in nec erat. Phasellus ac nulla ac turpis
porttitor auctor. Etiam eget posuere diam, ac feugiat lacus. Curabitur ornare
justo ut nulla congue, vitae posuere erat venenatis. Aliquam pulvinar eleifend
faucibus.

Etiam justo sem, faucibus malesuada purus a, ultrices efficitur ex.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Duis maximus dapibus mattis. Quisque sem ex, convallis eu
ultricies posuere.
"""

# 👍