[PATCH 2/3] spoolss: drop _spoolss_Get* SPOOLSS_BUFFER_OK usage

David Disseldorp ddiss at samba.org
Fri Dec 19 10:08:41 MST 2014


The ugly SPOOLSS_BUFFER_OK macro is called multiple times in succession,
which can be optimised by only performing the spoolss response bounds
check once.

Signed-off-by: David Disseldorp <ddiss at samba.org>
---
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 50 ++++++++++++++++++++---------
 1 file changed, 34 insertions(+), 16 deletions(-)

diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 14ec2bf..2c0edc3 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -4871,9 +4871,12 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
 
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
 					       r->out.info, r->in.level);
-	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
+	if (*r->out.needed > r->in.offered) {
+		r->out.info = NULL;
+		return WERR_INSUFFICIENT_BUFFER;
+	}
 
-	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+	return WERR_OK;
 
 err_info_free:
 	TALLOC_FREE(r->out.info);
@@ -5734,9 +5737,12 @@ WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
 
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
 					       r->out.info, r->in.level);
-	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
+	if (*r->out.needed > r->in.offered) {
+		r->out.info = NULL;
+		return WERR_INSUFFICIENT_BUFFER;
+	}
 
-	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+	return WERR_OK;
 
 err_info_free:
 	TALLOC_FREE(r->out.info);
@@ -7898,9 +7904,12 @@ WERROR _spoolss_GetForm(struct pipes_struct *p,
 
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
 					       r->out.info, r->in.level);
-	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
+	if (*r->out.needed > r->in.offered) {
+		r->out.info = NULL;
+		return WERR_INSUFFICIENT_BUFFER;
+	}
 
-	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+	return WERR_OK;
 }
 
 /****************************************************************************
@@ -8586,9 +8595,12 @@ WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
 
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
 					       r->out.info, r->in.level);
-	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
+	if (*r->out.needed > r->in.offered) {
+		r->out.info = NULL;
+		return WERR_INSUFFICIENT_BUFFER;
+	}
 
-	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+	return WERR_OK;
 }
 
 /****************************************************************
@@ -9595,10 +9607,13 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
 	}
 
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
-										   r->in.level);
-	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
+					       r->in.level);
+	if (*r->out.needed > r->in.offered) {
+		r->out.info = NULL;
+		return WERR_INSUFFICIENT_BUFFER;
+	}
 
-	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+	return WERR_OK;
 
 err_pinfo_free:
 	TALLOC_FREE(pinfo2);
@@ -9740,8 +9755,8 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
 done:
 	/* NOTE: do not replace type when returning WERR_MORE_DATA */
 
-	if (W_ERROR_IS_OK(result)) {
-		result = SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
+	if (W_ERROR_IS_OK(result) && (r->in.offered < *r->out.needed)) {
+		result = WERR_MORE_DATA;
 	}
 
 	talloc_free(tmp_ctx);
@@ -10212,10 +10227,13 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
 	}
 
 	*r->out.needed	= SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
-										   r->out.info, r->in.level);
-	r->out.info	= SPOOLSS_BUFFER_OK(r->out.info, NULL);
+					       r->out.info, r->in.level);
+	if (*r->out.needed > r->in.offered) {
+		r->out.info = NULL;
+		return WERR_INSUFFICIENT_BUFFER;
+	}
 
-	return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
+	return WERR_OK;
 
 err_info_free:
 	TALLOC_FREE(r->out.info);
-- 
2.1.2



More information about the samba-technical mailing list