fix: drop only control character references from Markdown, keep escaped quotes in env files, reject prefill-less inline comment edits, relabel the token's account

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-18 20:56:34 +02:00
1 parent dd2ec74d96
commit 33f3ff10b6
7 files changed
+65 -14

No files matched your search

+16 -2
View File
@@ -320,12 +320,12 @@ func parseEnvFile(data []byte) ([]envEntry, error) {
}
if quote := value[:min(len(value), 1)]; quote == `"` || quote == "'" {
// The value ends at the closing quote; only a # comment may follow it.
closing := strings.Index(value[1:], quote) + 1
closing := closingQuote(value, quote)
rest := strings.TrimSpace(value[min(closing+1, len(value)):])
if closing > 0 && (rest == "" || strings.HasPrefix(rest, "#")) {
value = value[1:closing]
if quote == `"` {
value = strings.ReplaceAll(value, `\n`, "\n")
value = strings.NewReplacer(`\n`, "\n", `\"`, `"`, `\\`, `\`).Replace(value)
}
entries = append(entries, envEntry{name, value})
continue
@@ -340,6 +340,20 @@ func parseEnvFile(data []byte) ([]envEntry, error) {
return entries, scanner.Err()
}
// closingQuote returns the index of the quote that closes the quoted value, or 0 when it is not
// closed. Inside double quotes a backslash escapes the next character.
func closingQuote(value, quote string) int {
for i := 1; i < len(value); i++ {
switch {
case quote == `"` && value[i] == '\\':
i++
case string(value[i]) == quote:
return i
}
}
return 0
}
func (a *application) actionValueDeleteCommand(secret bool, kind string) *cobra.Command {
var scope actionScopeFlags
cmd := &cobra.Command{
+7
View File
@@ -209,3 +209,10 @@ func TestVariableSetCountsCharactersNotBytes(t *testing.T) {
deps.Streams.In = strings.NewReader(strings.Repeat("é", 65537))
require.ErrorContains(t, Execute(context.Background(), deps, []string{"variable", "set", "WIDE", "-o", "acme"}), "65536 characters")
}
func TestParseEnvFileKeepsEscapedQuotes(t *testing.T) {
entries, err := parseEnvFile([]byte("A=\"say \\\"hi\\\" now\" # note\nB='it''s'\nC=\"back\\\\slash\\nline\"\n"))
require.NoError(t, err)
require.Equal(t, "say \"hi\" now", entries[0].value)
require.Equal(t, "back\\slash\nline", entries[2].value)
}
+4
View File
@@ -187,6 +187,10 @@ func (a *application) comment(cmd *cobra.Command, arg string, kind refKind, chan
// editComment replaces the text of comment, prefilling the prompt or editor with it.
func (a *application) editComment(cmd *cobra.Command, t target, comment services.Comment, f commentFlags) (runErr error) {
// An inline review comment is not fetched, so there is no text to start from.
if comment.Author == "" && !cmd.Flags().Changed("body") && !cmd.Flags().Changed("body-file") {
return clierr.Wrap(clierr.Usage, errors.New("an inline review comment cannot be prefilled; supply --body or --body-file"))
}
body, draft, err := a.readComment(cmd, f, comment.Body)
defer finishDraft(&draft, &runErr)
if err != nil {
+1 -1
View File
@@ -68,7 +68,7 @@ func TestCommentEditEditorSeedsCurrentBody(t *testing.T) {
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodGet && r.URL.Path == "/api/v1/repos/alice/project/issues/comments/7":
_, _ = w.Write([]byte(`{"id":7,"body":"current comment"}`))
_, _ = w.Write([]byte(`{"id":7,"body":"current comment","user":{"login":"alice"}}`))
case r.Method == http.MethodPatch && r.URL.Path == "/api/v1/repos/alice/project/issues/comments/7":
var options struct{ Body string }
require.NoError(t, json.NewDecoder(r.Body).Decode(&options))
+1 -1
View File
@@ -192,7 +192,7 @@ func (a *application) connect(ctx context.Context, req targetRequest) (target, e
if t.explicitUser() && !services.MatchAccount(t.User, actual) {
return t, clierr.Wrap(clierr.Authentication, errEnvironmentAccount)
}
if t.User == "" {
if !t.explicitUser() {
t.UserSource = "GITEA_TOKEN authenticated account"
}
t.User = actual