mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 08:34:30 +01:00 
			
		
		
		
	Avoid panic caused by broken payload when creating commit status (#23216)
When creating commit status for Actons jobs, a payload with nil `HeadCommit` will cause panic. Reported at: https://gitea.com/gitea/act_runner/issues/28#issuecomment-732166 Although the `HeadCommit` probably can not be nil after #23215, `CreateCommitStatus` should protect itself, to avoid being broken in the future. In addition, it's enough to print error log instead of returning err when `CreateCommitStatus` failed. --------- Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
		
							parent
							
								
									ca84a61761
								
							
						
					
					
						commit
						47b912cd52
					
				@ -150,7 +150,7 @@ func (s *Service) UpdateTask(
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := actions_service.CreateCommitStatus(ctx, task.Job); err != nil {
 | 
						if err := actions_service.CreateCommitStatus(ctx, task.Job); err != nil {
 | 
				
			||||||
		log.Error("Update commit status failed: %v", err)
 | 
							log.Error("Update commit status for job %v failed: %v", task.Job.ID, err)
 | 
				
			||||||
		// go on
 | 
							// go on
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/models/unit"
 | 
						"code.gitea.io/gitea/models/unit"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/actions"
 | 
						"code.gitea.io/gitea/modules/actions"
 | 
				
			||||||
	context_module "code.gitea.io/gitea/modules/context"
 | 
						context_module "code.gitea.io/gitea/modules/context"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
						"code.gitea.io/gitea/modules/timeutil"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/web"
 | 
						"code.gitea.io/gitea/modules/web"
 | 
				
			||||||
@ -214,15 +215,18 @@ func Rerun(ctx *context_module.Context) {
 | 
				
			|||||||
	job.Stopped = 0
 | 
						job.Stopped = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
						if err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
		if _, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped"); err != nil {
 | 
							_, err := actions_model.UpdateRunJob(ctx, job, builder.Eq{"status": status}, "task_id", "status", "started", "stopped")
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return actions_service.CreateCommitStatus(ctx, job)
 | 
					 | 
				
			||||||
	}); err != nil {
 | 
						}); err != nil {
 | 
				
			||||||
		ctx.Error(http.StatusInternalServerError, err.Error())
 | 
							ctx.Error(http.StatusInternalServerError, err.Error())
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
 | 
				
			||||||
 | 
							log.Error("Update commit status for job %v failed: %v", job.ID, err)
 | 
				
			||||||
 | 
							// go on
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(http.StatusOK, struct{}{})
 | 
						ctx.JSON(http.StatusOK, struct{}{})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -255,9 +259,6 @@ func Cancel(ctx *context_module.Context) {
 | 
				
			|||||||
			if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
 | 
								if err := actions_model.StopTask(ctx, job.TaskID, actions_model.StatusCancelled); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}); err != nil {
 | 
						}); err != nil {
 | 
				
			||||||
@ -265,6 +266,13 @@ func Cancel(ctx *context_module.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, job := range jobs {
 | 
				
			||||||
 | 
							if err := actions_service.CreateCommitStatus(ctx, job); err != nil {
 | 
				
			||||||
 | 
								log.Error("Update commit status for job %v failed: %v", job.ID, err)
 | 
				
			||||||
 | 
								// go on
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.JSON(http.StatusOK, struct{}{})
 | 
						ctx.JSON(http.StatusOK, struct{}{})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -43,6 +43,7 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
 | 
				
			|||||||
		return fmt.Errorf("find tasks: %w", err)
 | 
							return fmt.Errorf("find tasks: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						jobs := make([]*actions_model.ActionRunJob, 0, len(tasks))
 | 
				
			||||||
	for _, task := range tasks {
 | 
						for _, task := range tasks {
 | 
				
			||||||
		if err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
							if err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
			if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
 | 
								if err := actions_model.StopTask(ctx, task.ID, actions_model.StatusFailure); err != nil {
 | 
				
			||||||
@ -51,7 +52,8 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
 | 
				
			|||||||
			if err := task.LoadJob(ctx); err != nil {
 | 
								if err := task.LoadJob(ctx); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return CreateCommitStatus(ctx, task.Job)
 | 
								jobs = append(jobs, task.Job)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
		}); err != nil {
 | 
							}); err != nil {
 | 
				
			||||||
			log.Warn("Cannot stop task %v: %v", task.ID, err)
 | 
								log.Warn("Cannot stop task %v: %v", task.ID, err)
 | 
				
			||||||
			// go on
 | 
								// go on
 | 
				
			||||||
@ -61,6 +63,14 @@ func stopTasks(ctx context.Context, opts actions_model.FindTaskOptions) error {
 | 
				
			|||||||
			remove()
 | 
								remove()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, job := range jobs {
 | 
				
			||||||
 | 
							if err := CreateCommitStatus(ctx, job); err != nil {
 | 
				
			||||||
 | 
								log.Error("Update commit status for job %v failed: %v", job.ID, err)
 | 
				
			||||||
 | 
								// go on
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,14 +90,16 @@ func CancelAbandonedJobs(ctx context.Context) error {
 | 
				
			|||||||
		job.Status = actions_model.StatusCancelled
 | 
							job.Status = actions_model.StatusCancelled
 | 
				
			||||||
		job.Stopped = now
 | 
							job.Stopped = now
 | 
				
			||||||
		if err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
							if err := db.WithTx(ctx, func(ctx context.Context) error {
 | 
				
			||||||
			if _, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped"); err != nil {
 | 
								_, err := actions_model.UpdateRunJob(ctx, job, nil, "status", "stopped")
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return CreateCommitStatus(ctx, job)
 | 
					 | 
				
			||||||
		}); err != nil {
 | 
							}); err != nil {
 | 
				
			||||||
			log.Warn("cancel abandoned job %v: %v", job.ID, err)
 | 
								log.Warn("cancel abandoned job %v: %v", job.ID, err)
 | 
				
			||||||
			// go on
 | 
								// go on
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if err := CreateCommitStatus(ctx, job); err != nil {
 | 
				
			||||||
 | 
								log.Error("Update commit status for job %v failed: %v", job.ID, err)
 | 
				
			||||||
 | 
								// go on
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,16 @@ func CreateCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
 | 
				
			|||||||
		return fmt.Errorf("GetPushEventPayload: %w", err)
 | 
							return fmt.Errorf("GetPushEventPayload: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Since the payload comes from json data, we should check if it's broken, or it will cause panic
 | 
				
			||||||
 | 
						switch {
 | 
				
			||||||
 | 
						case payload.Repo == nil:
 | 
				
			||||||
 | 
							return fmt.Errorf("repo is missing in event payload")
 | 
				
			||||||
 | 
						case payload.Pusher == nil:
 | 
				
			||||||
 | 
							return fmt.Errorf("pusher is missing in event payload")
 | 
				
			||||||
 | 
						case payload.HeadCommit == nil:
 | 
				
			||||||
 | 
							return fmt.Errorf("head commit is missing in event payload")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID)
 | 
						creator, err := user_model.GetUserByID(ctx, payload.Pusher.ID)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("GetUserByID: %w", err)
 | 
							return fmt.Errorf("GetUserByID: %w", err)
 | 
				
			||||||
 | 
				
			|||||||
@ -187,7 +187,8 @@ func notify(ctx context.Context, input *notifyInput) error {
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			for _, job := range jobs {
 | 
								for _, job := range jobs {
 | 
				
			||||||
				if err := CreateCommitStatus(ctx, job); err != nil {
 | 
									if err := CreateCommitStatus(ctx, job); err != nil {
 | 
				
			||||||
					log.Error("CreateCommitStatus: %v", err)
 | 
										log.Error("Update commit status for job %v failed: %v", job.ID, err)
 | 
				
			||||||
 | 
										// go on
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user