Make escaping consistent for fish <-> fishd protocol

Fix fork guards to work in fishd
https://github.com/fish-shell/fish-shell/issues/339
This commit is contained in:
ridiculousfish 2012-10-08 14:47:25 -07:00
parent b67526aae8
commit 51de26960c
7 changed files with 69 additions and 27 deletions

View file

@ -375,7 +375,7 @@ static void react_to_variable_change(const wcstring &key) {
Universal variable callback function. This function makes sure the Universal variable callback function. This function makes sure the
proper events are triggered when an event occurs. proper events are triggered when an event occurs.
*/ */
static void universal_callback( int type, static void universal_callback( fish_message_type_t type,
const wchar_t *name, const wchar_t *name,
const wchar_t *val ) const wchar_t *val )
{ {
@ -395,6 +395,9 @@ static void universal_callback( int type,
str=L"ERASE"; str=L"ERASE";
break; break;
} }
default:
break;
} }
if( str ) if( str )

View file

@ -61,7 +61,7 @@ static int get_socket_count = 0;
static wchar_t * path; static wchar_t * path;
static wchar_t *user; static wchar_t *user;
static void (*start_fishd)(); static void (*start_fishd)();
static void (*external_callback)( int type, const wchar_t *name, const wchar_t *val ); static void (*external_callback)( fish_message_type_t type, const wchar_t *name, const wchar_t *val );
/** /**
Flag set to 1 when a barrier reply is recieved Flag set to 1 when a barrier reply is recieved
@ -165,7 +165,7 @@ static int get_socket( int fork_ok )
/** /**
Callback function used whenever a new fishd message is recieved Callback function used whenever a new fishd message is recieved
*/ */
static void callback( int type, const wchar_t *name, const wchar_t *val ) static void callback( fish_message_type_t type, const wchar_t *name, const wchar_t *val )
{ {
if( type == BARRIER_REPLY ) if( type == BARRIER_REPLY )
{ {
@ -250,7 +250,7 @@ static void reconnect()
void env_universal_init( wchar_t * p, void env_universal_init( wchar_t * p,
wchar_t *u, wchar_t *u,
void (*sf)(), void (*sf)(),
void (*cb)( int type, const wchar_t *name, const wchar_t *val )) void (*cb)( fish_message_type_t type, const wchar_t *name, const wchar_t *val ))
{ {
path=p; path=p;
user=u; user=u;

View file

@ -20,7 +20,7 @@ extern connection_t env_universal_server;
void env_universal_init( wchar_t * p, void env_universal_init( wchar_t * p,
wchar_t *u, wchar_t *u,
void (*sf)(), void (*sf)(),
void (*cb)( int type, const wchar_t *name, const wchar_t *val )); void (*cb)( fish_message_type_t type, const wchar_t *name, const wchar_t *val ));
/** /**
Free memory used by envuni Free memory used by envuni
*/ */

View file

@ -112,7 +112,7 @@ env_var_table_t env_universal_var;
/** /**
Callback function, should be called on all events Callback function, should be called on all events
*/ */
void (*callback)( int type, static void (*callback)( fish_message_type_t type,
const wchar_t *key, const wchar_t *key,
const wchar_t *val ); const wchar_t *val );
@ -405,7 +405,7 @@ static char *wcs2utf( const wchar_t *in )
void env_universal_common_init( void (*cb)(int type, const wchar_t *key, const wchar_t *val ) ) void env_universal_common_init( void (*cb)(fish_message_type_t type, const wchar_t *key, const wchar_t *val ) )
{ {
callback = cb; callback = cb;
} }
@ -592,7 +592,7 @@ void env_universal_common_set( const wchar_t *key, const wchar_t *val, int expor
/** /**
Parse message msg Parse message msg
*/ */
static void parse_message( wchar_t *msg, static void parse_message( wchar_t *msg,
connection_t *src ) connection_t *src )
{ {
// debug( 3, L"parse_message( %ls );", msg ); // debug( 3, L"parse_message( %ls );", msg );
@ -622,7 +622,8 @@ static void parse_message( wchar_t *msg,
val = tmp+1; val = tmp+1;
val = unescape( val, 0 ); val = unescape( val, 0 );
env_universal_common_set( key, val, exportv ); if (key && val)
env_universal_common_set( key, val, exportv );
free( val ); free( val );
free( key ); free( key );
@ -752,6 +753,15 @@ void try_send_all( connection_t *c )
} }
} }
/* The universal variable format has some funny escaping requirements; here we try to be safe */
static bool is_universal_safe_to_encode_directly(wchar_t c)
{
if (c < 32 || c > 128)
return false;
return iswalnum(c) || wcschr(L"/", c);
}
/** /**
Escape specified string Escape specified string
*/ */
@ -760,21 +770,22 @@ static wcstring full_escape( const wchar_t *in )
wcstring out; wcstring out;
for( ; *in; in++ ) for( ; *in; in++ )
{ {
if( *in < 32 ) wchar_t c = *in;
if (is_universal_safe_to_encode_directly(c))
{
out.push_back(c);
}
else if (c < 256)
{ {
append_format( out, L"\\x%.2x", *in ); append_format(out, L"\\x%.2x", c);
} }
else if( *in < 128 ) else if (c < 65536)
{ {
out.push_back(*in); append_format(out, L"\\u%.4x", c);
}
else if( *in < 65536 )
{
append_format( out, L"\\u%.4x", *in );
} }
else else
{ {
append_format( out, L"\\U%.8x", *in ); append_format(out, L"\\U%.8x", c);
} }
} }
return out; return out;
@ -803,7 +814,7 @@ void set_body(message_t *msg, ...)
} }
/* Returns an instance of message_t allocated via new */ /* Returns an instance of message_t allocated via new */
message_t *create_message( int type, message_t *create_message( fish_message_type_t type,
const wchar_t *key_in, const wchar_t *key_in,
const wchar_t *val_in ) const wchar_t *val_in )
{ {

View file

@ -40,15 +40,14 @@
/** /**
The different types of commands that can be sent between client/server The different types of commands that can be sent between client/server
*/ */
enum typedef enum
{ {
SET, SET,
SET_EXPORT, SET_EXPORT,
ERASE, ERASE,
BARRIER, BARRIER,
BARRIER_REPLY, BARRIER_REPLY,
} } fish_message_type_t;
;
/** /**
The size of the buffer used for reading from the socket The size of the buffer used for reading from the socket
@ -133,12 +132,12 @@ void try_send_all( connection_t *c );
/** /**
Create a messge with the specified properties Create a messge with the specified properties
*/ */
message_t *create_message( int type, const wchar_t *key, const wchar_t *val ); message_t *create_message( fish_message_type_t type, const wchar_t *key, const wchar_t *val );
/** /**
Init the library Init the library
*/ */
void env_universal_common_init(void (*cb)(int type, const wchar_t *key, const wchar_t *val ) ); void env_universal_common_init(void (*cb)(fish_message_type_t type, const wchar_t *key, const wchar_t *val ) );
/** /**
Destroy library data Destroy library data

View file

@ -410,10 +410,34 @@ static int fish_parse_opt( int argc, char **argv, const char **cmd_ptr )
parses commands from stdin or files, depending on arguments parses commands from stdin or files, depending on arguments
*/ */
static wcstring full_escape( const wchar_t *in )
{
wcstring out;
for( ; *in; in++ )
{
if( *in < 32 )
{
append_format( out, L"\\x%.2x", *in );
}
else if( *in < 128 )
{
out.push_back(*in);
}
else if( *in < 65536 )
{
append_format( out, L"\\u%.4x", *in );
}
else
{
append_format( out, L"\\U%.8x", *in );
}
}
return out;
}
extern int g_fork_count; extern int g_fork_count;
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
struct stat tmp;
int res=1; int res=1;
const char *cmd=0; const char *cmd=0;
int my_optind=0; int my_optind=0;
@ -425,7 +449,8 @@ int main( int argc, char **argv )
is_interactive_session=1; is_interactive_session=1;
program_name=L"fish"; program_name=L"fish";
stat("----------FISH_HIT_MAIN----------", &tmp); //struct stat tmp;
//stat("----------FISH_HIT_MAIN----------", &tmp);
my_optind = fish_parse_opt( argc, argv, &cmd ); my_optind = fish_parse_opt( argc, argv, &cmd );

View file

@ -496,7 +496,7 @@ unlock:
/** /**
Event handler. Broadcasts updates to all clients. Event handler. Broadcasts updates to all clients.
*/ */
static void broadcast( int type, const wchar_t *key, const wchar_t *val ) static void broadcast( fish_message_type_t type, const wchar_t *key, const wchar_t *val )
{ {
connection_t *c; connection_t *c;
message_t *msg; message_t *msg;
@ -540,6 +540,9 @@ static void daemonize()
case 0: case 0:
{ {
/* Ordinarily there's very limited things we will do after fork, due to multithreading. But fishd is safe because it's single threaded. So don't die in is_forked_child. */
setup_fork_guards();
/* /*
Make fishd ignore the HUP signal. Make fishd ignore the HUP signal.
*/ */
@ -557,6 +560,7 @@ static void daemonize()
act.sa_handler=&handle_term; act.sa_handler=&handle_term;
sigaction( SIGTERM, &act, 0); sigaction( SIGTERM, &act, 0);
break; break;
} }
default: default: