@@ -27,7 +27,11 @@ const path = require('path');
2727function initializeActionHandler ( message ) {
2828 if ( message . binary ) {
2929 // The code is a base64-encoded zip file.
30- return unzipInTmpDir ( message . code )
30+ ext = detectFileType ( message . code )
31+ if ( ext == 'unsupported' ) {
32+ return Promise . reject ( "There was an error uncompressing the action archive." ) ;
33+ }
34+ return extractInTmpDir ( message . code )
3135 . then ( moduleDir => {
3236 let parts = splitMainHandler ( message . main ) ;
3337 if ( parts === undefined ) {
@@ -138,21 +142,33 @@ class NodeActionRunner {
138142 * Note that this makes heavy use of shell commands because the environment is expected
139143 * to provide the required executables.
140144 */
141- function unzipInTmpDir ( zipFileContents ) {
145+ function extractInTmpDir ( archiveFileContents ) {
142146 const mkTempCmd = "mktemp -d XXXXXXXX" ;
143147 return exec ( mkTempCmd ) . then ( tmpDir => {
144148 return new Promise ( ( resolve , reject ) => {
145- const zipFile = path . join ( tmpDir , "action.zip" ) ;
146- fs . writeFile ( zipFile , zipFileContents , "base64" , err => {
147- if ( ! err ) resolve ( zipFile ) ;
149+ ext = detectFileType ( archiveFileContents )
150+ if ( ext == 'unsupported' ) {
151+ reject ( "There was an error Detecting the File type" ) ;
152+ }
153+ const archiveFile = path . join ( tmpDir , "action." + ext ) ;
154+ fs . writeFile ( archiveFile , archiveFileContents , "base64" , err => {
155+ if ( ! err ) resolve ( archiveFile ) ;
148156 else reject ( "There was an error reading the action archive." ) ;
149157 } ) ;
150158 } ) ;
151- } ) . then ( zipFile => {
159+ } ) . then ( archiveFile => {
152160 return exec ( mkTempCmd ) . then ( tmpDir => {
153- return exec ( "unzip -qq " + zipFile + " -d " + tmpDir )
161+ if ( ext === 'zip' ) {
162+ return exec ( "unzip -qq " + archiveFile + " -d " + tmpDir )
163+ . then ( res => path . resolve ( tmpDir ) )
164+ . catch ( error => Promise . reject ( "There was an error uncompressing the action archive." ) ) ;
165+ } else if ( ext === 'tar.gz' ) {
166+ return exec ( "tar -xzf " + archiveFile + " -C " + tmpDir + " > /dev/null" )
154167 . then ( res => path . resolve ( tmpDir ) )
155168 . catch ( error => Promise . reject ( "There was an error uncompressing the action archive." ) ) ;
169+ } else {
170+ return Promise . reject ( "There was an error uncompressing the action archive." ) ;
171+ }
156172 } ) ;
157173 } ) ;
158174}
@@ -198,3 +214,22 @@ module.exports = {
198214 NodeActionRunner,
199215 initializeActionHandler
200216} ;
217+
218+ // helper function to detect if base64string is zip or tar.gz
219+ // and returns the file ending
220+ function detectFileType ( base64String ) {
221+ // Decode the base64 string into binary data
222+ const binaryData = Buffer . from ( base64String , 'base64' ) ;
223+
224+ // Examine the first few bytes of the binary data to determine the file type
225+ const magicNumber = binaryData . slice ( 0 , 4 ) . toString ( 'hex' ) ;
226+
227+ if ( magicNumber === '504b0304' ) {
228+ return 'zip' ;
229+ // GZIP: 1f8b0808 maximum compression level, 1f8b0800 default compression
230+ } else if ( magicNumber === '1f8b0808' || magicNumber === '1f8b0800' ) {
231+ return 'tar.gz' ;
232+ } else {
233+ return 'unsupported' ;
234+ }
235+ }
0 commit comments