} catch ( ConfEditorParseError $e ) {
return $e->getMessage() . "\n" . $e->highlight( $text );
}
+
return "OK";
}
$key = isset( $op['key'] ) ? $op['key'] : null;
switch ( $type ) {
- case 'delete':
- list( $start, $end ) = $this->findDeletionRegion( $path );
- $this->replaceSourceRegion( $start, $end, false );
- break;
- case 'set':
- if ( isset( $this->pathInfo[$path] ) ) {
- list( $start, $end ) = $this->findValueRegion( $path );
- $encValue = $value; // var_export( $value, true );
- $this->replaceSourceRegion( $start, $end, $encValue );
+ case 'delete':
+ list( $start, $end ) = $this->findDeletionRegion( $path );
+ $this->replaceSourceRegion( $start, $end, false );
break;
- }
- // No existing path, fall through to append
- $slashPos = strrpos( $path, '/' );
- $key = var_export( substr( $path, $slashPos + 1 ), true );
- $path = substr( $path, 0, $slashPos );
- // Fall through
- case 'append':
- // Find the last array element
- $lastEltPath = $this->findLastArrayElement( $path );
- if ( $lastEltPath === false ) {
- throw new MWException( "Can't find any element of array \"$path\"" );
- }
- $lastEltInfo = $this->pathInfo[$lastEltPath];
+ case 'set':
+ if ( isset( $this->pathInfo[$path] ) ) {
+ list( $start, $end ) = $this->findValueRegion( $path );
+ $encValue = $value; // var_export( $value, true );
+ $this->replaceSourceRegion( $start, $end, $encValue );
+ break;
+ }
+ // No existing path, fall through to append
+ $slashPos = strrpos( $path, '/' );
+ $key = var_export( substr( $path, $slashPos + 1 ), true );
+ $path = substr( $path, 0, $slashPos );
+ // Fall through
+ case 'append':
+ // Find the last array element
+ $lastEltPath = $this->findLastArrayElement( $path );
+ if ( $lastEltPath === false ) {
+ throw new MWException( "Can't find any element of array \"$path\"" );
+ }
+ $lastEltInfo = $this->pathInfo[$lastEltPath];
- // Has it got a comma already?
- if ( strpos( $lastEltPath, '@extra' ) === false && !$lastEltInfo['hasComma'] ) {
- // No comma, insert one after the value region
- list( , $end ) = $this->findValueRegion( $lastEltPath );
- $this->replaceSourceRegion( $end - 1, $end - 1, ',' );
- }
+ // Has it got a comma already?
+ if ( strpos( $lastEltPath, '@extra' ) === false && !$lastEltInfo['hasComma'] ) {
+ // No comma, insert one after the value region
+ list( , $end ) = $this->findValueRegion( $lastEltPath );
+ $this->replaceSourceRegion( $end - 1, $end - 1, ',' );
+ }
- // Make the text to insert
- list( $start, $end ) = $this->findDeletionRegion( $lastEltPath );
+ // Make the text to insert
+ list( $start, $end ) = $this->findDeletionRegion( $lastEltPath );
- if ( $key === null ) {
- list( $indent, ) = $this->getIndent( $start );
- $textToInsert = "$indent$value,";
- } else {
- list( $indent, $arrowIndent ) =
- $this->getIndent( $start, $key, $lastEltInfo['arrowByte'] );
- $textToInsert = "$indent$key$arrowIndent=> $value,";
- }
- $textToInsert .= ( $indent === false ? ' ' : "\n" );
+ if ( $key === null ) {
+ list( $indent, ) = $this->getIndent( $start );
+ $textToInsert = "$indent$value,";
+ } else {
+ list( $indent, $arrowIndent ) =
+ $this->getIndent( $start, $key, $lastEltInfo['arrowByte'] );
+ $textToInsert = "$indent$key$arrowIndent=> $value,";
+ }
+ $textToInsert .= ( $indent === false ? ' ' : "\n" );
- // Insert the item
- $this->replaceSourceRegion( $end, $end, $textToInsert );
- break;
- case 'insert':
- // Find first array element
- $firstEltPath = $this->findFirstArrayElement( $path );
- if ( $firstEltPath === false ) {
- throw new MWException( "Can't find array element of \"$path\"" );
- }
- list( $start, ) = $this->findDeletionRegion( $firstEltPath );
- $info = $this->pathInfo[$firstEltPath];
-
- // Make the text to insert
- if ( $key === null ) {
- list( $indent, ) = $this->getIndent( $start );
- $textToInsert = "$indent$value,";
- } else {
- list( $indent, $arrowIndent ) =
- $this->getIndent( $start, $key, $info['arrowByte'] );
- $textToInsert = "$indent$key$arrowIndent=> $value,";
- }
- $textToInsert .= ( $indent === false ? ' ' : "\n" );
+ // Insert the item
+ $this->replaceSourceRegion( $end, $end, $textToInsert );
+ break;
+ case 'insert':
+ // Find first array element
+ $firstEltPath = $this->findFirstArrayElement( $path );
+ if ( $firstEltPath === false ) {
+ throw new MWException( "Can't find array element of \"$path\"" );
+ }
+ list( $start, ) = $this->findDeletionRegion( $firstEltPath );
+ $info = $this->pathInfo[$firstEltPath];
- // Insert the item
- $this->replaceSourceRegion( $start, $start, $textToInsert );
- break;
- default:
- throw new MWException( "Unrecognised operation: \"$type\"" );
+ // Make the text to insert
+ if ( $key === null ) {
+ list( $indent, ) = $this->getIndent( $start );
+ $textToInsert = "$indent$value,";
+ } else {
+ list( $indent, $arrowIndent ) =
+ $this->getIndent( $start, $key, $info['arrowByte'] );
+ $textToInsert = "$indent$key$arrowIndent=> $value,";
+ }
+ $textToInsert .= ( $indent === false ? ' ' : "\n" );
+
+ // Insert the item
+ $this->replaceSourceRegion( $start, $start, $textToInsert );
+ break;
+ default:
+ throw new MWException( "Unrecognised operation: \"$type\"" );
}
}
"Sorry, ConfEditor broke the file during editing and it won't parse anymore: " .
$e->getMessage() );
}
+
return $out;
}
$this->setVar( $vars, $parentPath, $name,
$this->parseScalar( $value ) );
}
+
return $vars;
}
if ( substr( $str, 0, 4 ) == 'null' ) {
return null;
}
+
// Must be some kind of numeric value, so let PHP's weak typing
// be useful for a change
return $str;
break;
}
}
+
return array( $regionStart, $regionEnd );
}
if ( $path['valueStartByte'] === false || $path['valueEndByte'] === false ) {
throw new MWException( "Can't find value region for path \"$pathName\"" );
}
+
return array( $path['valueStartByte'], $path['valueEndByte'] );
}
break;
}
}
+
return $extraPath;
}
return $candidatePath;
}
}
+
return false;
}
$arrowIndent = str_repeat( ' ', $arrowIndentLength );
}
}
+
return array( $indent, $arrowIndent );
}
}
switch ( $state ) {
- case 'file':
- $this->expect( T_OPEN_TAG );
- $token = $this->skipSpace();
- if ( $token->isEnd() ) {
- break 2;
- }
- $this->pushState( 'statement', 'file 2' );
- break;
- case 'file 2':
- $token = $this->skipSpace();
- if ( $token->isEnd() ) {
- break 2;
- }
- $this->pushState( 'statement', 'file 2' );
- break;
- case 'statement':
- $token = $this->skipSpace();
- if ( !$this->validatePath( $token->text ) ) {
- $this->error( "Invalid variable name \"{$token->text}\"" );
- }
- $this->nextPath( $token->text );
- $this->expect( T_VARIABLE );
- $this->skipSpace();
- $arrayAssign = false;
- if ( $this->currentToken()->type == '[' ) {
- $this->nextToken();
+ case 'file':
+ $this->expect( T_OPEN_TAG );
+ $token = $this->skipSpace();
+ if ( $token->isEnd() ) {
+ break 2;
+ }
+ $this->pushState( 'statement', 'file 2' );
+ break;
+ case 'file 2':
+ $token = $this->skipSpace();
+ if ( $token->isEnd() ) {
+ break 2;
+ }
+ $this->pushState( 'statement', 'file 2' );
+ break;
+ case 'statement':
+ $token = $this->skipSpace();
+ if ( !$this->validatePath( $token->text ) ) {
+ $this->error( "Invalid variable name \"{$token->text}\"" );
+ }
+ $this->nextPath( $token->text );
+ $this->expect( T_VARIABLE );
+ $this->skipSpace();
+ $arrayAssign = false;
+ if ( $this->currentToken()->type == '[' ) {
+ $this->nextToken();
+ $token = $this->skipSpace();
+ if ( !$token->isScalar() ) {
+ $this->error( "expected a string or number for the array key" );
+ }
+ if ( $token->type == T_CONSTANT_ENCAPSED_STRING ) {
+ $text = $this->parseScalar( $token->text );
+ } else {
+ $text = $token->text;
+ }
+ if ( !$this->validatePath( $text ) ) {
+ $this->error( "Invalid associative array name \"$text\"" );
+ }
+ $this->pushPath( $text );
+ $this->nextToken();
+ $this->skipSpace();
+ $this->expect( ']' );
+ $this->skipSpace();
+ $arrayAssign = true;
+ }
+ $this->expect( '=' );
+ $this->skipSpace();
+ $this->startPathValue();
+ if ( $arrayAssign ) {
+ $this->pushState( 'expression', 'array assign end' );
+ } else {
+ $this->pushState( 'expression', 'statement end' );
+ }
+ break;
+ case 'array assign end':
+ case 'statement end':
+ $this->endPathValue();
+ if ( $state == 'array assign end' ) {
+ $this->popPath();
+ }
+ $this->skipSpace();
+ $this->expect( ';' );
+ $this->nextPath( '@extra-' . ( $this->serial++ ) );
+ break;
+ case 'expression':
+ $token = $this->skipSpace();
+ if ( $token->type == T_ARRAY ) {
+ $this->pushState( 'array' );
+ } elseif ( $token->isScalar() ) {
+ $this->nextToken();
+ } elseif ( $token->type == T_VARIABLE ) {
+ $this->nextToken();
+ } else {
+ $this->error( "expected simple expression" );
+ }
+ break;
+ case 'array':
+ $this->skipSpace();
+ $this->expect( T_ARRAY );
+ $this->skipSpace();
+ $this->expect( '(' );
+ $this->skipSpace();
+ $this->pushPath( '@extra-' . ( $this->serial++ ) );
+ if ( $this->isAhead( ')' ) ) {
+ // Empty array
+ $this->pushState( 'array end' );
+ } else {
+ $this->pushState( 'element', 'array end' );
+ }
+ break;
+ case 'array end':
+ $this->skipSpace();
+ $this->popPath();
+ $this->expect( ')' );
+ break;
+ case 'element':
+ $token = $this->skipSpace();
+ // Look ahead to find the double arrow
+ if ( $token->isScalar() && $this->isAhead( T_DOUBLE_ARROW, 1 ) ) {
+ // Found associative element
+ $this->pushState( 'assoc-element', 'element end' );
+ } else {
+ // Not associative
+ $this->nextPath( '@next' );
+ $this->startPathValue();
+ $this->pushState( 'expression', 'element end' );
+ }
+ break;
+ case 'element end':
+ $token = $this->skipSpace();
+ if ( $token->type == ',' ) {
+ $this->endPathValue();
+ $this->markComma();
+ $this->nextToken();
+ $this->nextPath( '@extra-' . ( $this->serial++ ) );
+ // Look ahead to find ending bracket
+ if ( $this->isAhead( ")" ) ) {
+ // Found ending bracket, no continuation
+ $this->skipSpace();
+ } else {
+ // No ending bracket, continue to next element
+ $this->pushState( 'element' );
+ }
+ } elseif ( $token->type == ')' ) {
+ // End array
+ $this->endPathValue();
+ } else {
+ $this->error( "expected the next array element or the end of the array" );
+ }
+ break;
+ case 'assoc-element':
$token = $this->skipSpace();
if ( !$token->isScalar() ) {
$this->error( "expected a string or number for the array key" );
if ( !$this->validatePath( $text ) ) {
$this->error( "Invalid associative array name \"$text\"" );
}
- $this->pushPath( $text );
+ $this->nextPath( $text );
$this->nextToken();
$this->skipSpace();
- $this->expect( ']' );
+ $this->markArrow();
+ $this->expect( T_DOUBLE_ARROW );
$this->skipSpace();
- $arrayAssign = true;
- }
- $this->expect( '=' );
- $this->skipSpace();
- $this->startPathValue();
- if ( $arrayAssign ) {
- $this->pushState( 'expression', 'array assign end' );
- } else {
- $this->pushState( 'expression', 'statement end' );
- }
- break;
- case 'array assign end':
- case 'statement end':
- $this->endPathValue();
- if ( $state == 'array assign end' ) {
- $this->popPath();
- }
- $this->skipSpace();
- $this->expect( ';' );
- $this->nextPath( '@extra-' . ( $this->serial++ ) );
- break;
- case 'expression':
- $token = $this->skipSpace();
- if ( $token->type == T_ARRAY ) {
- $this->pushState( 'array' );
- } elseif ( $token->isScalar() ) {
- $this->nextToken();
- } elseif ( $token->type == T_VARIABLE ) {
- $this->nextToken();
- } else {
- $this->error( "expected simple expression" );
- }
- break;
- case 'array':
- $this->skipSpace();
- $this->expect( T_ARRAY );
- $this->skipSpace();
- $this->expect( '(' );
- $this->skipSpace();
- $this->pushPath( '@extra-' . ( $this->serial++ ) );
- if ( $this->isAhead( ')' ) ) {
- // Empty array
- $this->pushState( 'array end' );
- } else {
- $this->pushState( 'element', 'array end' );
- }
- break;
- case 'array end':
- $this->skipSpace();
- $this->popPath();
- $this->expect( ')' );
- break;
- case 'element':
- $token = $this->skipSpace();
- // Look ahead to find the double arrow
- if ( $token->isScalar() && $this->isAhead( T_DOUBLE_ARROW, 1 ) ) {
- // Found associative element
- $this->pushState( 'assoc-element', 'element end' );
- } else {
- // Not associative
- $this->nextPath( '@next' );
$this->startPathValue();
- $this->pushState( 'expression', 'element end' );
- }
- break;
- case 'element end':
- $token = $this->skipSpace();
- if ( $token->type == ',' ) {
- $this->endPathValue();
- $this->markComma();
- $this->nextToken();
- $this->nextPath( '@extra-' . ( $this->serial++ ) );
- // Look ahead to find ending bracket
- if ( $this->isAhead( ")" ) ) {
- // Found ending bracket, no continuation
- $this->skipSpace();
- } else {
- // No ending bracket, continue to next element
- $this->pushState( 'element' );
- }
- } elseif ( $token->type == ')' ) {
- // End array
- $this->endPathValue();
- } else {
- $this->error( "expected the next array element or the end of the array" );
- }
- break;
- case 'assoc-element':
- $token = $this->skipSpace();
- if ( !$token->isScalar() ) {
- $this->error( "expected a string or number for the array key" );
- }
- if ( $token->type == T_CONSTANT_ENCAPSED_STRING ) {
- $text = $this->parseScalar( $token->text );
- } else {
- $text = $token->text;
- }
- if ( !$this->validatePath( $text ) ) {
- $this->error( "Invalid associative array name \"$text\"" );
- }
- $this->nextPath( $text );
- $this->nextToken();
- $this->skipSpace();
- $this->markArrow();
- $this->expect( T_DOUBLE_ARROW );
- $this->skipSpace();
- $this->startPathValue();
- $this->pushState( 'expression' );
- break;
+ $this->pushState( 'expression' );
+ break;
}
}
if ( count( $this->stateStack ) ) {
} else {
$this->currentToken = $this->newTokenObj( $this->tokens[$this->pos] );
}
+
return $this->currentToken;
}
$this->lineNum = 1;
$this->colNum = 1;
$this->byteNum = 0;
+
return $this->currentToken;
}
}
$this->prevToken = $this->currentToken;
$this->setPos( $this->pos + 1 );
+
return $this->currentToken;
}
while ( $this->currentToken && $this->currentToken->isSkip() ) {
$this->nextToken();
}
+
return $this->currentToken;
}
return false;
}
}
+
return false;
}
*/
class ConfEditorParseError extends MWException {
var $lineNum, $colNum;
+
function __construct( $editor, $msg ) {
$this->lineNum = $editor->lineNum;
$this->colNum = $editor->colNum;
return "$line\n" . str_repeat( ' ', $this->colNum - 1 ) . "^\n";
}
}
+
return '';
}
-
}
/**
*/
public static function read( $fileName, $callback, $options = array() ) {
$zdr = new self( $fileName, $callback, $options );
+
return $zdr->execute();
}
} else {
if ( $this->eocdr['CD size'] == 0xffffffff
|| $this->eocdr['CD offset'] == 0xffffffff
- || $this->eocdr['CD entries total'] == 0xffff )
- {
+ || $this->eocdr['CD entries total'] == 0xffff
+ ) {
$this->error( 'zip-unsupported', 'Central directory header indicates ZIP64, ' .
'but we are in legacy mode. Rejecting this upload is necessary to avoid ' .
'opening vulnerabilities on clients using OpenJDK 7 or later.' );
}
fclose( $this->file );
+
return $status;
}
$this->error( 'zip-bad', 'trailing bytes after the end of the file comment' );
}
if ( $this->eocdr['disk'] !== 0
- || $this->eocdr['CD start disk'] !== 0 )
- {
+ || $this->eocdr['CD start disk'] !== 0
+ ) {
$this->error( 'zip-unsupported', 'more than one disk (in EOCDR)' );
}
$this->eocdr += $this->unpack(
*/
function readZip64EndOfCentralDirectoryRecord() {
if ( $this->eocdr64Locator['eocdr64 start disk'] != 0
- || $this->eocdr64Locator['number of disks'] != 0 )
- {
+ || $this->eocdr64Locator['number of disks'] != 0
+ ) {
$this->error( 'zip-unsupported', 'more than one disk (in EOCDR64 locator)' );
}
$this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory record' );
}
if ( $data['disk'] !== 0
- || $data['CD start disk'] !== 0 )
- {
+ || $data['CD start disk'] !== 0
+ ) {
$this->error( 'zip-unsupported', 'more than one disk (in EOCDR64)' );
}
}
$this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
'of central directory record' );
}
+
return array( $offset, $size );
}
$endPos = $this->eocdr['position'];
if ( $size == 0xffffffff
|| $offset == 0xffffffff
- || $numEntries == 0xffff )
- {
+ || $numEntries == 0xffff
+ ) {
$this->readZip64EndOfCentralDirectoryLocator();
if ( isset( $this->eocdr64Locator['eocdr64 offset'] ) ) {
$this->error( 'zip-bad', 'the central directory does not immediately precede the end ' .
'of central directory record' );
}
+
return array( $offset, $size );
}
$pos += $this->getStructSize( $variableInfo );
if ( $this->zip64 && (
- $data['compressed size'] == 0xffffffff
- || $data['uncompressed size'] == 0xffffffff
- || $data['local header offset'] == 0xffffffff ) )
- {
+ $data['compressed size'] == 0xffffffff
+ || $data['uncompressed size'] == 0xffffffff
+ || $data['local header offset'] == 0xffffffff )
+ ) {
$zip64Data = $this->unpackZip64Extra( $data['extra field'] );
if ( $zip64Data ) {
$data = $zip64Data + $data;
// Convert the character set in the file name
if ( !function_exists( 'iconv' )
- || $this->testBit( $data['general bits'], self::GENERAL_UTF8 ) )
- {
+ || $this->testBit( $data['general bits'], self::GENERAL_UTF8 )
+ ) {
$name = $data['name'];
} else {
$name = iconv( 'CP437', 'UTF-8', $data['name'] );
$stat = fstat( $this->file );
$this->fileLength = $stat['size'];
}
+
return $this->fileLength;
}
$bytePos = $segIndex * self::SEGSIZE;
if ( $bytePos >= $this->getFileLength() ) {
$this->buffer[$segIndex] = '';
+
return '';
}
if ( fseek( $this->file, $bytePos ) ) {
}
$this->buffer[$segIndex] = $seg;
}
+
return $this->buffer[$segIndex];
}
$size += $type;
}
}
+
return $size;
}
if ( is_array( $type ) ) {
list( $typeName, $fieldSize ) = $type;
switch ( $typeName ) {
- case 'string':
- $data[$key] = substr( $string, $pos, $fieldSize );
- $pos += $fieldSize;
- break;
- default:
- throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
+ case 'string':
+ $data[$key] = substr( $string, $pos, $fieldSize );
+ $pos += $fieldSize;
+ break;
+ default:
+ throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
}
} else {
// Unsigned little-endian integer