patch to source4/lib/wmi/tools/wmic.c

Dmitry Karasik dmitry at karasik.eu.org
Thu Jan 29 16:39:22 GMT 2009


Hello,

This is a report of a message I've sent some time ago, no-one has answered, but
talking on IRC I was advised to repost, so that's what I'm doing. Apologies if
you have already read that, but I would appreciate if anyone would respond to
this letter. At the very least, tell me what else can I do to have this patch
reviewed and/on included. Thank you!

I'm using wmic as a standalone program, and I need output of bin/wmic to be defined
with a more strict syntax, so that data that reported by the tool do not clash
with metadata characters (|,()) etc. Please find attached the patch that
changes the wmic output so that a) such characters are escaped b) null values
are reported as "(null)" string instead of "NULL", so a literal "NULL" that WMI
may eventually report won't be treated as a null value (if WMI reports "(null)"
then the output will be properly quoted as "\(null\)").

diff --git a/source4/lib/wmi/tools/wmic.c b/source4/lib/wmi/tools/wmic.c
index bbfe5ed..afbd1da 100644
--- a/source4/lib/wmi/tools/wmic.c
+++ b/source4/lib/wmi/tools/wmic.c
@@ -92,6 +92,37 @@ static void parse_args(int argc, char *argv[], struct program_args *pmyargs)
     poptFreeContext(pc);
 }
 
+static void
+escape_string( const char * src, char * dst, int len)
+{
+	char *p = dst, *end = dst + len - 1;
+	const char *q = src;
+
+	if ( q == NULL) {
+		strncpy( dst, "(null)", len);
+		return;
+	}
+
+	while ( *q && p <= end) {
+		if ( strchr( "|\\(),", *q)) {
+			*p++ = '\\';
+			*p++ = *q++;
+		} else if ( *q == '\n') {
+			*p++ = '\\';
+			*p++ = 'n';
+			q++;
+		} else if ( *q == '\r') {
+			*p++ = '\\';
+			*p++ = 'r';
+			q++;
+		} else {
+			*p++ = *q++;
+		}
+	}
+
+	*p++ = 0;
+}
+
 #define WERR_CHECK(msg) if (!W_ERROR_IS_OK(result)) { \
 			    DEBUG(0, ("ERROR: %s\n", msg)); \
 			    goto error; \
@@ -99,20 +130,33 @@ static void parse_args(int argc, char *argv[], struct program_args *pmyargs)
 			    DEBUG(1, ("OK   : %s\n", msg)); \
 			}
 
-#define RETURN_CVAR_ARRAY_STR(fmt, arr) {\
+#define RETURN_CVAR_ARRAY_STR_START(arr) {\
 	uint32_t i;\
 	char *r;\
 \
 	if (!arr) {\
-	        return talloc_strdup(mem_ctx, "NULL");\
+                return talloc_strdup(mem_ctx, "(null)");\
 	}\
 	r = talloc_strdup(mem_ctx, "(");\
-	for (i = 0; i < arr->count; ++i) {\
-		r = talloc_asprintf_append(r, fmt "%s", arr->item[i], (i+1 == arr->count)?"":",");\
+        for (i = 0; i < arr->count; ++i) {
+
+
+#define RETURN_CVAR_ARRAY_STR_END(fmt, arr, item) \
+		r = talloc_asprintf_append(r, fmt "%s", item, (i+1 == arr->count)?"":",");\
 	}\
 	return talloc_asprintf_append(r, ")");\
 }
 
+#define RETURN_CVAR_ARRAY_STR(fmt, arr) \
+	RETURN_CVAR_ARRAY_STR_START(arr) \
+	RETURN_CVAR_ARRAY_STR_END(fmt, arr, arr->item[i]) 
+
+#define RETURN_CVAR_ARRAY_ESCAPED(fmt, arr) \
+	RETURN_CVAR_ARRAY_STR_START(arr) \
+	char buf[2048]; \
+	escape_string( arr->item[i], buf, 2048); \
+	RETURN_CVAR_ARRAY_STR_END(fmt, arr, buf) 
+
 char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATION cimtype)
 {
 	switch (cimtype) {
@@ -129,7 +173,11 @@ char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATI
 	case CIM_BOOLEAN: return talloc_asprintf(mem_ctx, "%s", v->v_boolean?"True":"False");
 	case CIM_STRING:
 	case CIM_DATETIME:
-	case CIM_REFERENCE: return talloc_asprintf(mem_ctx, "%s", v->v_string);
+        case CIM_REFERENCE: {
+               char buf[2048];
+	       escape_string((char*) v-> v_string, buf, 2048);
+               return talloc_asprintf(mem_ctx, "%s", buf);
+        }
 	case CIM_CHAR16: return talloc_asprintf(mem_ctx, "Unsupported");
 	case CIM_OBJECT: return talloc_asprintf(mem_ctx, "Unsupported");
 	case CIM_ARR_SINT8: RETURN_CVAR_ARRAY_STR("%d", v->a_sint8);
@@ -143,9 +191,9 @@ char *string_CIMVAR(TALLOC_CTX *mem_ctx, union CIMVAR *v, enum CIMTYPE_ENUMERATI
 	case CIM_ARR_REAL32: RETURN_CVAR_ARRAY_STR("%f", v->a_real32);
 	case CIM_ARR_REAL64: RETURN_CVAR_ARRAY_STR("%f", v->a_real64);
 	case CIM_ARR_BOOLEAN: RETURN_CVAR_ARRAY_STR("%d", v->a_boolean);
-	case CIM_ARR_STRING: RETURN_CVAR_ARRAY_STR("%s", v->a_string);
-	case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY_STR("%s", v->a_datetime);
-	case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY_STR("%s", v->a_reference);
+        case CIM_ARR_STRING: RETURN_CVAR_ARRAY_ESCAPED("%s", v->a_string);
+        case CIM_ARR_DATETIME: RETURN_CVAR_ARRAY_ESCAPED("%s", v->a_datetime);
+        case CIM_ARR_REFERENCE: RETURN_CVAR_ARRAY_ESCAPED("%s", v->a_reference);
 	default: return talloc_asprintf(mem_ctx, "Unsupported");
 	}
 }


-- 
Sincerely,
	Dmitry Karasik


More information about the samba-technical mailing list