github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/dashboard/app/public_json_api.go (about)

     1  // Copyright 2021 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package main
     5  
     6  import (
     7  	"encoding/json"
     8  )
     9  
    10  // publicApiBugDescription is used to serve the /bug HTTP requests
    11  // and provide JSON description of the BUG. Backward compatible.
    12  type publicAPIBugDescription struct {
    13  	Version     int         `json:"version"`
    14  	Title       string      `json:"title,omitempty"`
    15  	ID          string      `json:"id"`
    16  	FixCommits  []vcsCommit `json:"fix-commits,omitempty"`
    17  	CauseCommit *vcsCommit  `json:"cause-commit,omitempty"`
    18  	// links to the discussions
    19  	Discussions []string                    `json:"discussions,omitempty"`
    20  	Crashes     []publicAPICrashDescription `json:"crashes,omitempty"`
    21  }
    22  
    23  type vcsCommit struct {
    24  	Title  string `json:"title"`
    25  	Link   string `json:"link,omitempty"`
    26  	Hash   string `json:"hash,omitempty"`
    27  	Repo   string `json:"repo,omitempty"`
    28  	Branch string `json:"branch,omitempty"`
    29  }
    30  
    31  type publicAPICrashDescription struct {
    32  	Title               string `json:"title"`
    33  	SyzReproducer       string `json:"syz-reproducer,omitempty"`
    34  	CReproducer         string `json:"c-reproducer,omitempty"`
    35  	KernelConfig        string `json:"kernel-config,omitempty"`
    36  	KernelSourceGit     string `json:"kernel-source-git,omitempty"`
    37  	KernelSourceCommit  string `json:"kernel-source-commit,omitempty"`
    38  	SyzkallerGit        string `json:"syzkaller-git,omitempty"`
    39  	SyzkallerCommit     string `json:"syzkaller-commit,omitempty"`
    40  	CompilerDescription string `json:"compiler-description,omitempty"`
    41  	Architecture        string `json:"architecture,omitempty"`
    42  	CrashReport         string `json:"crash-report-link,omitempty"`
    43  }
    44  
    45  func getExtAPIDescrForBugPage(bugPage *uiBugPage) *publicAPIBugDescription {
    46  	return &publicAPIBugDescription{
    47  		Version: 1,
    48  		Title:   bugPage.Bug.Title,
    49  		ID:      bugPage.Bug.ID,
    50  		Discussions: func() []string {
    51  			if bugPage.Bug.ExternalLink == "" {
    52  				return nil
    53  			}
    54  			return []string{bugPage.Bug.ExternalLink}
    55  		}(),
    56  		FixCommits: getBugFixCommits(bugPage.Bug),
    57  		CauseCommit: func() *vcsCommit {
    58  			if bugPage.BisectCause == nil || bugPage.BisectCause.Commit == nil {
    59  				return nil
    60  			}
    61  			bisectCause := bugPage.BisectCause
    62  			return &vcsCommit{
    63  				Title:  bisectCause.Commit.Title,
    64  				Link:   bisectCause.Commit.Link,
    65  				Hash:   bisectCause.Commit.Hash,
    66  				Repo:   bisectCause.KernelRepo,
    67  				Branch: bisectCause.KernelBranch}
    68  		}(),
    69  		Crashes: func() []publicAPICrashDescription {
    70  			var res []publicAPICrashDescription
    71  			for _, crash := range bugPage.Crashes.Crashes {
    72  				res = append(res, publicAPICrashDescription{
    73  					Title:              crash.Title,
    74  					SyzReproducer:      crash.ReproSyzLink,
    75  					CReproducer:        crash.ReproCLink,
    76  					KernelConfig:       crash.KernelConfigLink,
    77  					KernelSourceGit:    crash.KernelCommitLink,
    78  					KernelSourceCommit: crash.KernelCommit,
    79  					SyzkallerGit:       crash.SyzkallerCommitLink,
    80  					SyzkallerCommit:    crash.SyzkallerCommit,
    81  					// TODO: add the CompilerDescription
    82  					// TODO: add the Architecture
    83  					CrashReport: crash.ReportLink,
    84  				})
    85  			}
    86  			return res
    87  		}(),
    88  	}
    89  }
    90  
    91  func getBugFixCommits(bug *uiBug) []vcsCommit {
    92  	var res []vcsCommit
    93  	for _, commit := range bug.Commits {
    94  		res = append(res, vcsCommit{
    95  			Title:  commit.Title,
    96  			Link:   commit.Link,
    97  			Hash:   commit.Hash,
    98  			Repo:   commit.Repo,
    99  			Branch: commit.Branch,
   100  		})
   101  	}
   102  	return res
   103  }
   104  
   105  type publicAPIBugGroup struct {
   106  	Version int `json:"version"`
   107  	Bugs    []publicAPIBug
   108  }
   109  
   110  type publicAPIBug struct {
   111  	Title       string      `json:"title,omitempty"`
   112  	Link        string      `json:"link"`
   113  	LastUpdated string      `json:"last-updated,omitempty"`
   114  	FixCommits  []vcsCommit `json:"fix-commits,omitempty"`
   115  }
   116  
   117  func getExtAPIDescrForBugGroups(bugGroups []*uiBugGroup) *publicAPIBugGroup {
   118  	return &publicAPIBugGroup{
   119  		Version: 1,
   120  		Bugs: func() []publicAPIBug {
   121  			var res []publicAPIBug
   122  			for _, group := range bugGroups {
   123  				for _, bug := range group.Bugs {
   124  					res = append(res, publicAPIBug{
   125  						Title:      bug.Title,
   126  						Link:       bug.Link,
   127  						FixCommits: getBugFixCommits(bug),
   128  					})
   129  				}
   130  			}
   131  			return res
   132  		}(),
   133  	}
   134  }
   135  
   136  func GetJSONDescrFor(page interface{}) ([]byte, error) {
   137  	var res interface{}
   138  	switch i := page.(type) {
   139  	case *uiBugPage:
   140  		res = getExtAPIDescrForBugPage(i)
   141  	case *uiTerminalPage:
   142  		res = getExtAPIDescrForBugGroups([]*uiBugGroup{i.Bugs})
   143  	case *uiMainPage:
   144  		res = getExtAPIDescrForBugGroups(i.Groups)
   145  	default:
   146  		return nil, ErrClientNotFound
   147  	}
   148  	return json.MarshalIndent(res, "", "\t")
   149  }