<commit_before>package main

import (
	"errors"
	"fmt"
	"os/exec"
	"strings"

	"golang.org/x/sys/unix"
)

// WrapperCommand represents components necessary for OAuth2l request
type WrapperCommand struct {
	RequestType string
	Args
	Credential
}

// Args type used for unmarshalled JSON
type Args map[string]interface{}

// Credential type used for storing JSON-formatted credentials
type Credential map[string]interface{}

// Execute will capture output of OAuth2l CLI using command args
func (wc WrapperCommand) Execute() (output string, err error) {
	// combinedArgs used to represent command arguments in an array
	args, err := combinedArgs(wc)

	if err != nil {
		return "", err
	}

	// Check if credential is provided to include in oauth2l command
	if wc.Credential != nil {
		// Symlink path to memory file
		path, err := getCredentialPath(wc.Credential)

		if err != nil {
			return "", err
		}

		args = append(args, "--credentials", path)
	}

	// Execute command and capture output
	command := exec.Command("oauth2l", args...)
	byteBuffer, err := command.Output()

	// Convert byteBuffer to string and remove newline character
	output = strings.TrimSuffix(string(byteBuffer), "\n")
	
	return output, err
}

func allocateMemFile(credential Credential) (descriptor int, err error) {
	// Init cred with credential body
	cred := credential["credential"]

	byteArray := []byte(cred.(string))

	// Create an anonymous file on the RAM, once all references to descriptor are dropped, file is released
	descriptor, err = unix.MemfdCreate("credential", 0)

	if err != nil {
		return 0, err
	}

	// Truncate file size to match size of our credential body
	err = unix.Ftruncate(descriptor, int64(len(byteArray)))
	if err != nil {
		return 0, err
	}

	// Map file to memory and assign virtual address
	data, err := unix.Mmap(descriptor, 0, len(byteArray), unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED)
	if err != nil {
		return 0, err
	}

	// Copy credential body into allocated memory
	copy(data, byteArray)

	// Delete data memory mapping as body is now written to memory
	err = unix.Munmap(data)
	if err != nil {
		return 0, err
	}

	// Returns file descriptor
	return descriptor, nil
}

func getCredentialPath(credential Credential) (path string, err error) {
	// Gets a file descriptor for a memory allocated credential file
	descriptor, err := allocateMemFile(credential)

	if err != nil {
		return "", err
	}

	path = fmt.Sprintf("/proc/self/fd/%d", descriptor)

	return path, nil
}

// Returns args in flattened array<commit_msg>Change memory permission to read-only for access to descriptor<commit_after>package main

import (
	"errors"
	"fmt"
	"os/exec"
	"strings"

	"golang.org/x/sys/unix"
)

// WrapperCommand represents components necessary for OAuth2l request
type WrapperCommand struct {
	RequestType string
	Args
	Credential
}

// Args type used for unmarshalled JSON
type Args map[string]interface{}

// Credential type used for storing JSON-formatted credentials
type Credential map[string]interface{}

// Execute will capture output of OAuth2l CLI using command args
func (wc WrapperCommand) Execute() (output string, err error) {
	// combinedArgs used to represent command arguments in an array
	args, err := combinedArgs(wc)

	if err != nil {
		return "", err
	}

	// Check if credential is provided to include in oauth2l command
	if wc.Credential != nil {
		// Symlink path to memory file
		path, err := getCredentialPath(wc.Credential)

		if err != nil {
			return "", err
		}

		args = append(args, "--credentials", path)
	}

	// Execute command and capture output
	command := exec.Command("oauth2l", args...)
	byteBuffer, err := command.Output()

	// Convert byteBuffer to string and remove newline character
	output = strings.TrimSuffix(string(byteBuffer), "\n")
	
	return output, err
}

func allocateMemFile(credential Credential) (descriptor int, err error) {
	// Init cred with credential body
	cred := credential["credential"]

	byteArray := []byte(cred.(string))

	// Create an anonymous file on the RAM, once all references to descriptor are dropped, file is released
	descriptor, err = unix.MemfdCreate("credential", 0)

	if err != nil {
		return 0, err
	}

	// Truncate file size to match size of our credential body
	err = unix.Ftruncate(descriptor, int64(len(byteArray)))
	if err != nil {
		return 0, err
	}

	// Map file to memory and assign virtual address
	address, err := unix.Mmap(descriptor, 0, len(byteArray), unix.PROT_READ, unix.MAP_SHARED)
	if err != nil {
		return 0, err
	}

	// Copy credential body into allocated memory
	copy(address, byteArray)

	// Delete data memory mapping as body is now written to memory
	err = unix.Munmap(address)
	if err != nil {
		return 0, err
	}

	// Returns file descriptor
	return descriptor, nil
}

func getCredentialPath(credential Credential) (path string, err error) {
	// Gets a file descriptor for a memory allocated credential file
	descriptor, err := allocateMemFile(credential)

	if err != nil {
		return "", err
	}

	path = fmt.Sprintf("/proc/self/fd/%d", descriptor)

	return path, nil
}

// Returns args in flattened array
{'fraction_non_alphanumeric': 0.10148611654282362, 'fraction_numerical': 0.004692999608916699, 'mean_word_length': 3.8760724499523356, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2804284', 'n_tokens_mistral': 1653, 'n_tokens_neox': 1547, 'n_words': 573}