66 parsePermissionKeys ,
77 parseRepoArg ,
88 readBoundedGitHubErrorText ,
9+ readBoundedGitHubJson ,
910 resolveGitHubFetchTimeoutMs ,
1011} from "../../scripts/gh-read.js" ;
1112
@@ -68,11 +69,7 @@ describe("gh-read helpers", () => {
6869 } ) ;
6970
7071 it ( "times out stalled GitHub API response body reads" , async ( ) => {
71- const response = {
72- ok : true ,
73- status : 200 ,
74- json : ( ) => new Promise ( ( ) => { } ) ,
75- } as Response ;
72+ const response = new Response ( new ReadableStream ( { } ) , { status : 200 } ) ;
7673 const request = githubJson ( "/app/installations" , "token" , undefined , {
7774 timeoutMs : 5 ,
7875 fetchImpl : ( ( ) => Promise . resolve ( response ) ) as typeof fetch ,
@@ -94,6 +91,53 @@ describe("gh-read helpers", () => {
9491 expect ( text . length ) . toBeLessThan ( 4200 ) ;
9592 } ) ;
9693
94+ it ( "reads bounded GitHub API JSON responses" , async ( ) => {
95+ await expect ( readBoundedGitHubJson ( new Response ( '{"id":123}' ) , 1024 ) ) . resolves . toEqual ( {
96+ id : 123 ,
97+ } ) ;
98+ } ) ;
99+
100+ it ( "rejects oversized GitHub API JSON responses by content length" , async ( ) => {
101+ let canceled = false ;
102+ const response = new Response (
103+ new ReadableStream ( {
104+ cancel ( ) {
105+ canceled = true ;
106+ } ,
107+ } ) ,
108+ {
109+ headers : {
110+ "content-length" : "1025" ,
111+ } ,
112+ } ,
113+ ) ;
114+
115+ await expect ( readBoundedGitHubJson ( response , 1024 ) ) . rejects . toMatchObject ( {
116+ code : "ETOOBIG" ,
117+ message : "GitHub API response body exceeded 1024 bytes" ,
118+ } ) ;
119+ expect ( canceled ) . toBe ( true ) ;
120+ } ) ;
121+
122+ it ( "rejects oversized streamed GitHub API JSON responses" , async ( ) => {
123+ const encoder = new TextEncoder ( ) ;
124+ const response = new Response (
125+ new ReadableStream ( {
126+ start ( controller ) {
127+ controller . enqueue ( encoder . encode ( '{"body":"' ) ) ;
128+ controller . enqueue ( encoder . encode ( "x" . repeat ( 1024 ) ) ) ;
129+ controller . enqueue ( encoder . encode ( '"}' ) ) ;
130+ controller . close ( ) ;
131+ } ,
132+ } ) ,
133+ ) ;
134+
135+ await expect ( readBoundedGitHubJson ( response , 1024 ) ) . rejects . toMatchObject ( {
136+ code : "ETOOBIG" ,
137+ message : "GitHub API response body exceeded 1024 bytes" ,
138+ } ) ;
139+ } ) ;
140+
97141 it ( "rejects invalid GitHub API timeout values" , ( ) => {
98142 expect ( resolveGitHubFetchTimeoutMs ( "1000" ) ) . toBe ( 1000 ) ;
99143 expect ( ( ) => resolveGitHubFetchTimeoutMs ( "1s" ) ) . toThrow (
0 commit comments