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
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 *val )
{
@ -395,6 +395,9 @@ static void universal_callback( int type,
str=L"ERASE";
break;
}
default:
break;
}
if( str )

View file

@ -61,7 +61,7 @@ static int get_socket_count = 0;
static wchar_t * path;
static wchar_t *user;
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
@ -165,7 +165,7 @@ static int get_socket( int fork_ok )
/**
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 )
{
@ -250,7 +250,7 @@ static void reconnect()
void env_universal_init( wchar_t * p,
wchar_t *u,
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;
user=u;

View file

@ -20,7 +20,7 @@ extern connection_t env_universal_server;
void env_universal_init( wchar_t * p,
wchar_t *u,
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
*/

View file

@ -112,7 +112,7 @@ env_var_table_t env_universal_var;
/**
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 *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;
}
@ -622,7 +622,8 @@ static void parse_message( wchar_t *msg,
val = tmp+1;
val = unescape( val, 0 );
env_universal_common_set( key, val, exportv );
if (key && val)
env_universal_common_set( key, val, exportv );
free( val );
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
*/
@ -760,21 +770,22 @@ static wcstring full_escape( const wchar_t *in )
wcstring out;
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);
}
else if( *in < 65536 )
{
append_format( out, L"\\u%.4x", *in );
append_format(out, L"\\u%.4x", c);
}
else
{
append_format( out, L"\\U%.8x", *in );
append_format(out, L"\\U%.8x", c);
}
}
return out;
@ -803,7 +814,7 @@ void set_body(message_t *msg, ...)
}
/* 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 *val_in )
{

View file

@ -40,15 +40,14 @@
/**
The different types of commands that can be sent between client/server
*/
enum
typedef enum
{
SET,
SET_EXPORT,
ERASE,
BARRIER,
BARRIER_REPLY,
}
;
} fish_message_type_t;
/**
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
*/
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
*/
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

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
*/
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;
int main( int argc, char **argv )
{
struct stat tmp;
int res=1;
const char *cmd=0;
int my_optind=0;
@ -425,7 +449,8 @@ int main( int argc, char **argv )
is_interactive_session=1;
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 );

View file

@ -496,7 +496,7 @@ unlock:
/**
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;
message_t *msg;
@ -540,6 +540,9 @@ static void daemonize()
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.
*/
@ -557,6 +560,7 @@ static void daemonize()
act.sa_handler=&handle_term;
sigaction( SIGTERM, &act, 0);
break;
}
default: