September 2nd, 2006

404

safe code (programming lytdybr)

Был код:


struct{
 ...
 HWND dlg;
}set;/*global runtime settings*/

void write_log(int level, char* message){
        static char text[65536];
        static SYSTEMTIME time;
        GetLocalTime(&time);
        snprintf(text,65536,"%d: %02d:%02d:%02d> %s\n",level, time.wHour, time.wMinute,time.wSecond,  message);
		SendDlgItemMessage(set.dlg, ET_LOG, EM_SETSEL,   2147483647,   2147483647);
		SendDlgItemMessage(set.dlg, ET_LOG, EM_REPLACESEL, FALSE, (LPARAM) text); 

		
}


Код делал простую вещь - выводил в EDITTEXT контрол строку (просто лог на экране). Но ведь небезопасненько как-то..

Вот что получилось:


struct{
 ...
 int disable_msg_box_alert;
 HWND dlg;
}set;/*global runtime settings*/


void internal_error( const char* text ){
/*display a message box with error, only once per application  run*/
	if( !set.disable_msg_box_alert ){
		MessageBox( set.dlg, text, "Internal error, please restart application.", MB_ICONWARNING );
		set.disable_msg_box_alert = 1;
	}
}

void internal_error( const char* text ){
/*display a message box with error, only once per application  run*/
	if( !set.disable_msg_box_alert ){
		MessageBox( set.dlg, text, "Internal error, please restart application.", MB_ICONWARNING );
		set.disable_msg_box_alert = 1;
	}
}

void write_log(int level, char* message){

        static char text[65536];
        static SYSTEMTIME time;
        GetLocalTime( &time );


	if( !set.dlg ){
		internal_error( "log disabled (unable to init dialog)" );
		return;
	}

	if( !wsprintf( text, "%1d: %02d:%02d:%02d>", level, time.wHour, time.wMinute, time.wSecond ) ){
		internal_error( "wsprintf failed (log message skipped)" );
		return;
	}

	if( lstrlen(message)>=65535 - lstrlen( text ) ){
		internal_error( "log message too long (skipped)\n");
		return;
	}

	if( !lstrcat( text, message ) ){
		internal_error( "lstrcat failed (log message skipped)\n" );
		return;
	}

	SendDlgItemMessage( set.dlg, ET_LOG, EM_SETSEL,   2147483647,   2147483647 );
	SendDlgItemMessage( set.dlg, ET_LOG, EM_REPLACESEL, FALSE, (LPARAM)text ); 

}



Обратите внимание - предусмотрены все случаи. Нет лога, сбои в выделении памяти, сбои в обработке строк... Но насколько же это занудно... -_-