Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git

Adds media types

AuthorDave Jarvis <email>
Date2026-02-10 12:25:50 GMT-0800
Commit0e3e558b9dfcdca6367cf8abef2f554400609d4d
Parent021d1af
Delta80 lines added, 22 lines removed, 58-line increase
Git.php
class Git {
private const CHUNK_SIZE = 128;
+ private const MAX_READ_SIZE = 1048576;
private string $repoPath;
public function read( string $sha ): string {
- $loosePath = $this->getLoosePath( $sha );
-
- if( file_exists( $loosePath ) ) {
- $rawContent = file_get_contents( $loosePath );
- $inflated = $rawContent ? @gzuncompress( $rawContent ) : false;
+ $size = $this->getObjectSize( $sha );
- return $inflated ? explode( "\0", $inflated, 2 )[1] : '';
+ if( $size > self::MAX_READ_SIZE ) {
+ return '';
}
- return $this->packs->read( $sha ) ?? '';
+ $content = '';
+
+ $this->slurp( $sha, function( $chunk ) use ( &$content ) {
+ $content .= $chunk;
+ } );
+
+ return $content;
}
public function stream( string $sha, callable $callback ): void {
- $data = $this->read( $sha );
+ $this->slurp( $sha, $callback );
+ }
- if( $data !== '' ) {
+ private function slurp( string $sha, callable $callback ): void {
+ $loosePath = $this->getLoosePath( $sha );
+
+ if( file_exists( $loosePath ) ) {
+ $fileHandle = @fopen( $loosePath, 'rb' );
+
+ if( !$fileHandle ) return;
+
+ $inflator = inflate_init( ZLIB_ENCODING_DEFLATE );
+ $buffer = '';
+ $headerFound = false;
+
+ while( !feof( $fileHandle ) ) {
+ $chunk = fread( $fileHandle, 16384 );
+ $inflatedChunk = @inflate_add( $inflator, $chunk );
+
+ if( $inflatedChunk === false ) break;
+
+ if( !$headerFound ) {
+ $buffer .= $inflatedChunk;
+ $nullPos = strpos( $buffer, "\0" );
+
+ if( $nullPos !== false ) {
+ $body = substr( $buffer, $nullPos + 1 );
+
+ if( $body !== '' ) {
+ $callback( $body );
+ }
+
+ $headerFound = true;
+ $buffer = '';
+ }
+ } else {
+ $callback( $inflatedChunk );
+ }
+ }
+
+ fclose( $fileHandle );
+ return;
+ }
+
+ $data = $this->packs->read( $sha );
+
+ if( $data !== null && $data !== '' ) {
$callback( $data );
}
GitDiff.php
class GitDiff {
private $git;
+ private const MAX_DIFF_SIZE = 1048576;
public function __construct(Git $git) {
private function createChange($type, $path, $oldSha, $newSha) {
+ // Check file sizes before reading content to prevent OOM
+ $oldSize = $oldSha ? $this->git->getObjectSize($oldSha) : 0;
+ $newSize = $newSha ? $this->git->getObjectSize($newSha) : 0;
+
+ // If file is too large, skip diffing and treat as binary
+ if ($oldSize > self::MAX_DIFF_SIZE || $newSize > self::MAX_DIFF_SIZE) {
+ return [
+ 'type' => $type,
+ 'path' => $path,
+ 'is_binary' => true,
+ 'hunks' => []
+ ];
+ }
+
$oldContent = $oldSha ? $this->git->read($oldSha) : '';
$newContent = $newSha ? $this->git->read($newSha) : '';
GitPacks.php
private function skipSize( string $data, int &$position ): void {
- while( ord( $data[$position++] ) & 128 ) {
- // Empty loop body
+ $length = strlen( $data );
+
+ while( $position < $length && (ord( $data[$position++] ) & 128) ) {
+ // Loop continues while MSB is 1
}
}
MediaTypeSniffer.php
'rmd' => [self::CAT_TEXT, 'text/r-markdown'],
'txt' => [self::CAT_TEXT, 'text/plain'],
- 'yaml' => [self::CAT_TEXT, 'text/yaml'],
- 'yml' => [self::CAT_TEXT, 'text/yaml'],
'gradle' => [self::CAT_TEXT, 'text/plain'],
'gitignore' => [self::CAT_TEXT, 'text/plain'],
'tex' => [self::CAT_TEXT, 'application/x-tex'],
'lyx' => [self::CAT_TEXT, 'application/x-lyx'],
'bat' => [self::CAT_TEXT, 'application/x-msdos-program'],
'ts' => [self::CAT_TEXT, 'application/typescript'],
'log' => [self::CAT_TEXT, 'text/plain'],
'ini' => [self::CAT_TEXT, 'text/plain'],
'conf' => [self::CAT_TEXT, 'text/plain'],
- 'zip' => [self::CAT_ARCHIVE, 'application/zip'],
'jpg' => [self::CAT_IMAGE, 'image/jpeg'],
'jpeg' => [self::CAT_IMAGE, 'image/jpeg'],
// Config formats
+ 'yaml' => [self::CAT_TEXT, 'text/yaml'],
+ 'yml' => [self::CAT_TEXT, 'text/yaml'],
'toml' => [self::CAT_TEXT, 'application/toml'],
'env' => [self::CAT_TEXT, 'text/plain'],
'sql' => [self::CAT_TEXT, 'application/sql'],
'html' => [self::CAT_TEXT, 'text/html'],
+ 'xhtml' => [self::CAT_TEXT, 'text/xhtml'],
'css' => [self::CAT_TEXT, 'text/css'],
'js' => [self::CAT_TEXT, 'application/javascript'],
// Build / DevOps
'dockerfile'=> [self::CAT_TEXT, 'text/plain'],
+ 'containerfile'=> [self::CAT_TEXT, 'text/plain'],
'makefile' => [self::CAT_TEXT, 'text/x-makefile'],
'cmake' => [self::CAT_TEXT, 'text/x-cmake'],
- 'gitmodules'=> [self::CAT_TEXT, 'text/plain'],
- 'editorconfig'=> [self::CAT_TEXT, 'text/plain'],
-
- // Dependency / package files
- 'lock' => [self::CAT_TEXT, 'text/plain'],
- 'pipfile' => [self::CAT_TEXT, 'text/plain'],
- 'pipfile.lock' => [self::CAT_TEXT, 'application/json'],
- 'requirements.txt' => [self::CAT_TEXT, 'text/plain'],
// Misc text