Opened 12 years ago

Closed 8 years ago

#862 closed New Feature (wontfix)

SpellerPages for PHP while Safe Mode is On (solution within)

Reported by: reubenhelms@… Owned by:
Priority: Normal Milestone:
Component: Server : PHP Version:
Keywords: SF HasPatch Cc: reubenhelms@…

Description

I've been using the FCKEditor for Joomla plugin, that mostly uses the PHP side of things.

Because of the usage of shell_exec, it is not possible to use aspell is Safe Mode is on.

However, I've made a few changes to print_checker_results() in editor/dialog/fck_spellerpages/server-scripts/spellchecker.php that should provide aspell functionality while Safe Mode is on.

The there are two security settings that will be required, however.

First, you must allow the operation of proc_open. Secondly, you must have aspell located or linked into your safe_mode_exec_dir.

Things to note about these changes:

I'm not primarily a PHP coder, but I've dabbled. There are probably better ways to do what I've done, but these get the job done.

I did have a version that streamed the $tempfile straight out to the read pipe, but decided to read from the file instead, for simplicity.

Also decided to keep the error file if things didnt go so well.

Anyway, I hope these changes get added to the next release. If there is a more formal way I should be submitting this, like a patch, please let me know.

Here are the changes:

// from when the tempfile is generated
fclose($fh);

$othertemp = tempnam($tempfiledir, 'aspell_error_');^M
$descarray = array (
0 => array("file", $tempfile, "r"),
1 => array("pipe", "w"),
2 => array("file", $othertemp, "a"));

$process = proc_open($aspell_prog . " " . $aspell_opts,
$descarray, $pipes);

if (is_resource($process)) {
$aspellret = '';
while (!feof($pipes[1])) {
$aspellret .= fread($pipes[1], 8192);
}
fclose($pipes[1]);
$rc = proc_close($process);
}

// previous read if( $aspellret = shell_exec( $cmd )) {
if( $rc == 0) {^M
unlink($othertemp); // remove error file if no error
$linesout = explode( "\n", $aspellret );^M
// continue process the output as normal

Moved from SF:
http://sourceforge.net/tracker/index.php?func=detail&aid=1417319&group_id=75348&atid=543656

Change History (4)

comment:1 Changed 12 years ago by Martin Kou

Cc: reubenhelms@… added
Reporter: changed from Martin Kou to reubenhelms@…

Well, the previous solution here was just dandy until PHP 4.3.4 made tempnam() incompatible with safe mode (or there is a bug in PHP where it looses the user that it is running as).

Anyway, this prompted me to make further modifications to the php spellchecker function to not use tempnam() and just use 100% pipes. This means that it will work without having to write files to the local file system (none that might break safe mode, anyway).

So here is the complete function, wrapped up in a pre tag.

<pre>
function print_checker_results() {

	global $aspell_prog;
	global $aspell_opts;
	global $tempfiledir;
	global $textinputs;
	global $input_separator;
	$aspell_err = "";

	# open temp file handle, add the submitted text.
	if ($fh = tmpfile()) {
		for( $i = 0; $i < count( $textinputs ); $i++ ) {
			$text = urldecode( $textinputs[$i] );
			$lines = explode( "\n", $text );
			fwrite ( $fh, "%\n" ); # exit terse mode
			fwrite ( $fh, "^$input_separator\n" );
			fwrite ( $fh, "!\n" ); # enter terse mode
			foreach( $lines as $key=>$value ) {
				# use carat on each line to escape possible aspell commands
				fwrite( $fh, "^$value\n" );
			}
		}
		$fhsize = ftell($fh);
		fseek($fh, 0);

		# exec aspell command - redirect STDERR to STDOUT
		$cmd = "$aspell_prog $aspell_opts 2>&1";
		$descarray = array (
			0 => array("pipe", "r"),
			1 => array("pipe", "w"),
			2 => array("pipe", "w"));
			
		$process = proc_open($aspell_prog . " " . $aspell_opts,
$descarray, $pipes);
		
		if (is_resource($process)) {
		    fwrite($pipes[0], fread($fh, $fhsize));
		    fclose($pipes[0]);
			$aspellret = '';
			while (!feof($pipes[1])) {
				$aspellret .= fread($pipes[1], 8192);
			}
			fclose($pipes[1]);
			fclose($pipes[2]);
			$rc = proc_close($process);
		}
		
		fclose($fh);
				
		if ($rc == 0) {
			$linesout = explode( "\n", $aspellret );
			$index = 0;
			$text_input_index = -1;
			# parse each line of aspell return
			foreach( $linesout as $key=>$val ) {
				$chardesc = substr( $val, 0, 1 );
				/* if '&', then not in dictionary but has suggestions
				# if '#', then not in dictionary and no suggestions
				# if '*', then it is a delimiter between text inputs
				# if '@' then version info */
				if( $chardesc == '&' || $chardesc == '#' ) {
					$line = explode( " ", $val, 5 );
					print_words_elem( $line[1], $index, $text_input_index );
					if( isset( $line[4] )) {
						$suggs = explode( ", ", $line[4] );
					} else {
						$suggs = array();
					}
					print_suggs_elem( $suggs, $index, $text_input_index );
					$index++;
				} elseif( $chardesc == '*' ) {
					$text_input_index++;
					print_textindex_decl( $text_input_index );
					$index = 0;
				} elseif( $chardesc != '@' && $chardesc != "" ) {
					# assume this is error output
					$aspell_err .= $val;
				}
			}
			if( $aspell_err ) {
				$aspell_err = "Error executing `$cmd`\\n$aspell_err";
				error_handler( $aspell_err );
			}
		} else {
			error_handler( "System error: Aspell program execution
failed (`$cmd`)" );
		}
	} else {
		error_handler( "System error: Could not open file
'$tempfile' for writing" );
	}

}
</pre>

Moved from SF. Original poster: reubenhelms

comment:2 Changed 12 years ago by Alfonso Martínez de Lizarrondo

Component: GeneralServer : PHP

comment:3 Changed 11 years ago by Wojciech Olchawa

Keywords: HasPatch added

comment:4 Changed 8 years ago by Wiktor Walc

Resolution: wontfix
Status: newclosed

FCKeditor is no longer maintained and this bug does not occur in CKEditor as a different spell checking system is used there, so I'm closing this one.

Note: See TracTickets for help on using tickets.
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy