mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
parent
b1f8676347
commit
57206e7274
10 changed files with 114 additions and 56 deletions
|
@ -4,7 +4,7 @@ parameters:
|
||||||
defaults: &defaults
|
defaults: &defaults
|
||||||
resource_class: large
|
resource_class: large
|
||||||
docker:
|
docker:
|
||||||
- image: bepsays/ci-hugoreleaser:1.22200.20000
|
- image: bepsays/ci-hugoreleaser:1.22200.20100
|
||||||
environment: &buildenv
|
environment: &buildenv
|
||||||
GOMODCACHE: /root/project/gomodcache
|
GOMODCACHE: /root/project/gomodcache
|
||||||
version: 2
|
version: 2
|
||||||
|
@ -60,7 +60,7 @@ jobs:
|
||||||
environment:
|
environment:
|
||||||
<<: [*buildenv]
|
<<: [*buildenv]
|
||||||
docker:
|
docker:
|
||||||
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22200.20000
|
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22200.20100
|
||||||
steps:
|
steps:
|
||||||
- *restore-cache
|
- *restore-cache
|
||||||
- &attach-workspace
|
- &attach-workspace
|
||||||
|
|
|
@ -16,7 +16,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// The current is built with 446a5dcf5a3230ce9832682d8f521071d8a34a2b (go 1.22 dev. Thu Oct 5 12:20:11 2023 -0700)
|
// The current is built with db6097f8cb [release-branch.go1.22] go1.22.1
|
||||||
|
// TODO(bep) preserve the staticcheck.conf file.
|
||||||
fmt.Println("Forking ...")
|
fmt.Println("Forking ...")
|
||||||
defer fmt.Println("Done ...")
|
defer fmt.Println("Done ...")
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ package fmtsort_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var compareTests = [][]reflect.Value{
|
var compareTests = [][]reflect.Value{
|
||||||
|
@ -191,14 +191,14 @@ func sprintKey(key reflect.Value) string {
|
||||||
var (
|
var (
|
||||||
ints [3]int
|
ints [3]int
|
||||||
chans = makeChans()
|
chans = makeChans()
|
||||||
// pin runtime.Pinner
|
pin runtime.Pinner
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeChans() []chan int {
|
func makeChans() []chan int {
|
||||||
cs := []chan int{make(chan int), make(chan int), make(chan int)}
|
cs := []chan int{make(chan int), make(chan int), make(chan int)}
|
||||||
// Order channels by address. See issue #49431.
|
// Order channels by address. See issue #49431.
|
||||||
for i := range cs {
|
for i := range cs {
|
||||||
reflect.ValueOf(cs[i]).UnsafePointer()
|
pin.Pin(reflect.ValueOf(cs[i]).UnsafePointer())
|
||||||
}
|
}
|
||||||
sort.Slice(cs, func(i, j int) bool {
|
sort.Slice(cs, func(i, j int) bool {
|
||||||
return uintptr(reflect.ValueOf(cs[i]).UnsafePointer()) < uintptr(reflect.ValueOf(cs[j]).UnsafePointer())
|
return uintptr(reflect.ValueOf(cs[i]).UnsafePointer()) < uintptr(reflect.ValueOf(cs[j]).UnsafePointer())
|
||||||
|
|
|
@ -172,13 +172,31 @@ func jsValEscaper(args ...any) string {
|
||||||
// cyclic data. This may be an unacceptable DoS risk.
|
// cyclic data. This may be an unacceptable DoS risk.
|
||||||
b, err := json.Marshal(a)
|
b, err := json.Marshal(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Put a space before comment so that if it is flush against
|
// While the standard JSON marshaller does not include user controlled
|
||||||
|
// information in the error message, if a type has a MarshalJSON method,
|
||||||
|
// the content of the error message is not guaranteed. Since we insert
|
||||||
|
// the error into the template, as part of a comment, we attempt to
|
||||||
|
// prevent the error from either terminating the comment, or the script
|
||||||
|
// block itself.
|
||||||
|
//
|
||||||
|
// In particular we:
|
||||||
|
// * replace "*/" comment end tokens with "* /", which does not
|
||||||
|
// terminate the comment
|
||||||
|
// * replace "</script" with "\x3C/script", and "<!--" with
|
||||||
|
// "\x3C!--", which prevents confusing script block termination
|
||||||
|
// semantics
|
||||||
|
//
|
||||||
|
// We also put a space before the comment so that if it is flush against
|
||||||
// a division operator it is not turned into a line comment:
|
// a division operator it is not turned into a line comment:
|
||||||
// x/{{y}}
|
// x/{{y}}
|
||||||
// turning into
|
// turning into
|
||||||
// x//* error marshaling y:
|
// x//* error marshaling y:
|
||||||
// second line of error message */null
|
// second line of error message */null
|
||||||
return fmt.Sprintf(" /* %s */null ", strings.ReplaceAll(err.Error(), "*/", "* /"))
|
errStr := err.Error()
|
||||||
|
errStr = strings.ReplaceAll(errStr, "*/", "* /")
|
||||||
|
errStr = strings.ReplaceAll(errStr, "</script", `\x3C/script`)
|
||||||
|
errStr = strings.ReplaceAll(errStr, "<!--", `\x3C!--`)
|
||||||
|
return fmt.Sprintf(" /* %s */null ", errStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: maybe post-process output to prevent it from containing
|
// TODO: maybe post-process output to prevent it from containing
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package template
|
package template
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -106,61 +107,72 @@ func TestNextJsCtx(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type jsonErrType struct{}
|
||||||
|
|
||||||
|
func (e *jsonErrType) MarshalJSON() ([]byte, error) {
|
||||||
|
return nil, errors.New("beep */ boop </script blip <!--")
|
||||||
|
}
|
||||||
|
|
||||||
func TestJSValEscaper(t *testing.T) {
|
func TestJSValEscaper(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
x any
|
x any
|
||||||
js string
|
js string
|
||||||
|
skipNest bool
|
||||||
}{
|
}{
|
||||||
{int(42), " 42 "},
|
{int(42), " 42 ", false},
|
||||||
{uint(42), " 42 "},
|
{uint(42), " 42 ", false},
|
||||||
{int16(42), " 42 "},
|
{int16(42), " 42 ", false},
|
||||||
{uint16(42), " 42 "},
|
{uint16(42), " 42 ", false},
|
||||||
{int32(-42), " -42 "},
|
{int32(-42), " -42 ", false},
|
||||||
{uint32(42), " 42 "},
|
{uint32(42), " 42 ", false},
|
||||||
{int16(-42), " -42 "},
|
{int16(-42), " -42 ", false},
|
||||||
{uint16(42), " 42 "},
|
{uint16(42), " 42 ", false},
|
||||||
{int64(-42), " -42 "},
|
{int64(-42), " -42 ", false},
|
||||||
{uint64(42), " 42 "},
|
{uint64(42), " 42 ", false},
|
||||||
{uint64(1) << 53, " 9007199254740992 "},
|
{uint64(1) << 53, " 9007199254740992 ", false},
|
||||||
// ulp(1 << 53) > 1 so this loses precision in JS
|
// ulp(1 << 53) > 1 so this loses precision in JS
|
||||||
// but it is still a representable integer literal.
|
// but it is still a representable integer literal.
|
||||||
{uint64(1)<<53 + 1, " 9007199254740993 "},
|
{uint64(1)<<53 + 1, " 9007199254740993 ", false},
|
||||||
{float32(1.0), " 1 "},
|
{float32(1.0), " 1 ", false},
|
||||||
{float32(-1.0), " -1 "},
|
{float32(-1.0), " -1 ", false},
|
||||||
{float32(0.5), " 0.5 "},
|
{float32(0.5), " 0.5 ", false},
|
||||||
{float32(-0.5), " -0.5 "},
|
{float32(-0.5), " -0.5 ", false},
|
||||||
{float32(1.0) / float32(256), " 0.00390625 "},
|
{float32(1.0) / float32(256), " 0.00390625 ", false},
|
||||||
{float32(0), " 0 "},
|
{float32(0), " 0 ", false},
|
||||||
{math.Copysign(0, -1), " -0 "},
|
{math.Copysign(0, -1), " -0 ", false},
|
||||||
{float64(1.0), " 1 "},
|
{float64(1.0), " 1 ", false},
|
||||||
{float64(-1.0), " -1 "},
|
{float64(-1.0), " -1 ", false},
|
||||||
{float64(0.5), " 0.5 "},
|
{float64(0.5), " 0.5 ", false},
|
||||||
{float64(-0.5), " -0.5 "},
|
{float64(-0.5), " -0.5 ", false},
|
||||||
{float64(0), " 0 "},
|
{float64(0), " 0 ", false},
|
||||||
{math.Copysign(0, -1), " -0 "},
|
{math.Copysign(0, -1), " -0 ", false},
|
||||||
{"", `""`},
|
{"", `""`, false},
|
||||||
{"foo", `"foo"`},
|
{"foo", `"foo"`, false},
|
||||||
// Newlines.
|
// Newlines.
|
||||||
{"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`},
|
{"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`, false},
|
||||||
// "\v" == "v" on IE 6 so use "\u000b" instead.
|
// "\v" == "v" on IE 6 so use "\u000b" instead.
|
||||||
{"\t\x0b", `"\t\u000b"`},
|
{"\t\x0b", `"\t\u000b"`, false},
|
||||||
{struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`},
|
{struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`, false},
|
||||||
{[]any{}, "[]"},
|
{[]any{}, "[]", false},
|
||||||
{[]any{42, "foo", nil}, `[42,"foo",null]`},
|
{[]any{42, "foo", nil}, `[42,"foo",null]`, false},
|
||||||
{[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`},
|
{[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`, false},
|
||||||
{"<!--", `"\u003c!--"`},
|
{"<!--", `"\u003c!--"`, false},
|
||||||
{"-->", `"--\u003e"`},
|
{"-->", `"--\u003e"`, false},
|
||||||
{"<![CDATA[", `"\u003c![CDATA["`},
|
{"<![CDATA[", `"\u003c![CDATA["`, false},
|
||||||
{"]]>", `"]]\u003e"`},
|
{"]]>", `"]]\u003e"`, false},
|
||||||
{"</script", `"\u003c/script"`},
|
{"</script", `"\u003c/script"`, false},
|
||||||
{"\U0001D11E", "\"\U0001D11E\""}, // or "\uD834\uDD1E"
|
{"\U0001D11E", "\"\U0001D11E\"", false}, // or "\uD834\uDD1E"
|
||||||
{nil, " null "},
|
{nil, " null ", false},
|
||||||
|
{&jsonErrType{}, " /* json: error calling MarshalJSON for type *template.jsonErrType: beep * / boop \\x3C/script blip \\x3C!-- */null ", true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
if js := jsValEscaper(test.x); js != test.js {
|
if js := jsValEscaper(test.x); js != test.js {
|
||||||
t.Errorf("%+v: want\n\t%q\ngot\n\t%q", test.x, test.js, js)
|
t.Errorf("%+v: want\n\t%q\ngot\n\t%q", test.x, test.js, js)
|
||||||
}
|
}
|
||||||
|
if test.skipNest {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// Make sure that escaping corner cases are not broken
|
// Make sure that escaping corner cases are not broken
|
||||||
// by nesting.
|
// by nesting.
|
||||||
a := []any{test.x}
|
a := []any{test.x}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package testenv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -60,6 +61,13 @@ func tryExec() error {
|
||||||
// may as well use the same path so that this branch can be tested without
|
// may as well use the same path so that this branch can be tested without
|
||||||
// an ios environment.
|
// an ios environment.
|
||||||
|
|
||||||
|
if !testing.Testing() {
|
||||||
|
// This isn't a standard 'go test' binary, so we don't know how to
|
||||||
|
// self-exec in a way that should succeed without side effects.
|
||||||
|
// Just forget it.
|
||||||
|
return errors.New("can't probe for exec support with a non-test executable")
|
||||||
|
}
|
||||||
|
|
||||||
// We know that this is a test executable. We should be able to run it with a
|
// We know that this is a test executable. We should be able to run it with a
|
||||||
// no-op flag to check for overall exec support.
|
// no-op flag to check for overall exec support.
|
||||||
exe, err := os.Executable()
|
exe, err := os.Executable()
|
||||||
|
|
|
@ -17,5 +17,5 @@ import (
|
||||||
var Sigquit = os.Kill
|
var Sigquit = os.Kill
|
||||||
|
|
||||||
func syscallIsNotSupported(err error) bool {
|
func syscallIsNotSupported(err error) bool {
|
||||||
return errors.Is(err, fs.ErrPermission)
|
return errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ func TestGoToolLocation(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modified by Hugo.
|
||||||
func TestHasGoBuild(t *testing.T) {
|
func TestHasGoBuild(t *testing.T) {
|
||||||
// Removed by Hugo.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMustHaveExec(t *testing.T) {
|
func TestMustHaveExec(t *testing.T) {
|
||||||
|
@ -73,7 +73,7 @@ func TestMustHaveExec(t *testing.T) {
|
||||||
t.Errorf("expected MustHaveExec to skip on %v", runtime.GOOS)
|
t.Errorf("expected MustHaveExec to skip on %v", runtime.GOOS)
|
||||||
}
|
}
|
||||||
case "ios":
|
case "ios":
|
||||||
if b := testenv.Builder(); strings.HasSuffix(b, "-corellium") && !hasExec {
|
if b := testenv.Builder(); isCorelliumBuilder(b) && !hasExec {
|
||||||
// Most ios environments can't exec, but the corellium builder can.
|
// Most ios environments can't exec, but the corellium builder can.
|
||||||
t.Errorf("expected MustHaveExec not to skip on %v", b)
|
t.Errorf("expected MustHaveExec not to skip on %v", b)
|
||||||
}
|
}
|
||||||
|
@ -106,3 +106,23 @@ func TestCleanCmdEnvPWD(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Error("PWD not set in cmd.Env")
|
t.Error("PWD not set in cmd.Env")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isCorelliumBuilder(builderName string) bool {
|
||||||
|
// Support both the old infra's builder names and the LUCI builder names.
|
||||||
|
// The former's names are ad-hoc so we could maintain this invariant on
|
||||||
|
// the builder side. The latter's names are structured, and "corellium" will
|
||||||
|
// appear as a "host" suffix after the GOOS and GOARCH, which always begin
|
||||||
|
// with an underscore.
|
||||||
|
return strings.HasSuffix(builderName, "-corellium") || strings.Contains(builderName, "_corellium")
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmulatedBuilder(builderName string) bool {
|
||||||
|
// Support both the old infra's builder names and the LUCI builder names.
|
||||||
|
// The former's names are ad-hoc so we could maintain this invariant on
|
||||||
|
// the builder side. The latter's names are structured, and the signifier
|
||||||
|
// of emulation "emu" will appear as a "host" suffix after the GOOS and
|
||||||
|
// GOARCH because it modifies the run environment in such a way that it
|
||||||
|
// the target GOOS and GOARCH may not match the host. This suffix always
|
||||||
|
// begins with an underscore.
|
||||||
|
return strings.HasSuffix(builderName, "-emu") || strings.Contains(builderName, "_emu")
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func syscallIsNotSupported(err error) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, fs.ErrPermission) {
|
if errors.Is(err, fs.ErrPermission) || errors.Is(err, errors.ErrUnsupported) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,6 @@ func (a *ActionNode) tree() *Tree {
|
||||||
|
|
||||||
func (a *ActionNode) Copy() Node {
|
func (a *ActionNode) Copy() Node {
|
||||||
return a.tr.newAction(a.Pos, a.Line, a.Pipe.CopyPipe())
|
return a.tr.newAction(a.Pos, a.Line, a.Pipe.CopyPipe())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandNode holds a command (a pipeline inside an evaluating action).
|
// CommandNode holds a command (a pipeline inside an evaluating action).
|
||||||
|
|
Loading…
Reference in a new issue