Attached is a patch that adds a "size" parameter to all APIs that
manipulate variable-sized XML configuration data.

I have tested *all* operations that the concordance application exposes,
in particular, read/write config/firmware in xml/binary mode.

The diff looks a little scarier than I feel it is; perhaps apply it then
compare the code visually...

Explanation of API changes:

delete_blob: I figured this didn't need a return code. If it does,
revert the .h change, but I figure it should return 0, not 1, to be
consistent with other APIs.

post_*, verify_xml_config: Add size parameter to allow implementation
not to parse beyond the end of the XML data.

write_config_to_file: Simply re-ordered the parameters so that size was
immediately after the pointer that it's the size of, to be consistent
with all other APIs accepting a size parameter.

find_config_binary*: Merged these 2 functions into 1, which also
performs the appropriate error-checking. This "lifts" the error checking
logic into libconcord, so applications don't have to know how to do it.
The new API also returns both location and size of the binary data, for
passing to all the other APIs.

read_firmware_from_file: I wasn't going to touch any of the firmware
APIs, but since this one can return XML data, it also needs to return
the size of the XML data just like read_config_from_file.

extract_firmware_binary: Again, this can parse XML, so it needs a size
parameter.

GetTag: Add size parameter; the point of the change.

Post: Add size parameter to pass to GetTag.

Implementation notes, other than simply reacting to API changes:

concordance: Binary firmware writes: Don't extract_firmware_binary, nor
free the not-separately-allocated firmware_bin, when in binary mode.

verify_xml_config: "Lift" validation of binary size into
find_config_binary, and re-use that validation to avoid duplication of
logic.

extract_firmware_binary: Validate there isn't more firmware in the XML
file than we expect, to avoid writing past end of allocated data.

All XML file reading: Allocate arrays as exactly the size we want to
read, and don't put a "NULL" character after the read data, because now
we pass the size everywhere.

Post (and a few other places): When calling GetTag repeatedly, and
starting the search from where the last one left off, we need to
re-calculate the size of data left each time "xml_size-(x-xml)".

GetTag: Ended up re-writing this quite a bit to make use of the new size
parameter. Hopefully the comments explain how this works pretty well.

I think that's it...

Things remaining:

I wonder if we should do this: Everywhere that uses GetTag currently
searches the entire XML file for the tag. I wonder if we shouldn't
always search for </INFORMATION>, then only search *before* that point,
just to make sure we don't accidentally find something within the binary
portion. Such a change would probably be purely internal to the
functions though, so no API changes would be required (unless we want to
perhaps pre-parse this bit during file read, and return a structure with
ptr/size/bin_ptr/bin_size to clients...)
? concordance/.concordance.c.swp
? concordance/.deps
? concordance/.libs
? concordance/Makefile
? concordance/Makefile.in
? concordance/aclocal.m4
? concordance/autom4te.cache
? concordance/concordance
? concordance/config.guess
? concordance/config.h
? concordance/config.h.in
? concordance/config.log
? concordance/config.status
? concordance/config.sub
? concordance/configure
? concordance/depcomp
? concordance/install-sh
? concordance/libtool
? concordance/ltmain.sh
? concordance/missing
? concordance/stamp-h1
? consnoop/snoop
? libconcord/.deps
? libconcord/.libconcord.cpp.swp
? libconcord/.libconcord.h.swp
? libconcord/.libs
? libconcord/.web.h.swp
? libconcord/Makefile
? libconcord/Makefile.in
? libconcord/aclocal.m4
? libconcord/autom4te.cache
? libconcord/binaryfile.lo
? libconcord/config.guess
? libconcord/config.h
? libconcord/config.h.in
? libconcord/config.log
? libconcord/config.status
? libconcord/config.sub
? libconcord/configure
? libconcord/depcomp
? libconcord/install-sh
? libconcord/libconcord.la
? libconcord/libconcord.lo
? libconcord/libtool
? libconcord/libusbhid.lo
? libconcord/ltmain.sh
? libconcord/missing
? libconcord/remote.lo
? libconcord/remote_z.lo
? libconcord/stamp-h1
? libconcord/usblan.lo
? libconcord/web.lo
Index: concordance/concordance.c
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.c,v
retrieving revision 1.10
diff -u -r1.10 concordance.c
--- concordance/concordance.c	16 Mar 2008 07:00:52 -0000	1.10
+++ concordance/concordance.c	16 Mar 2008 20:05:11 -0000
@@ -157,7 +157,7 @@
 		return err;
 	}
 
-	if ((err = write_config_to_file(config, file_name, size,
+	if ((err = write_config_to_file(config, size, file_name,
 			(*options).binary))) {
 		return err;
 	}
@@ -196,31 +196,23 @@
 
 	uint8_t *data;
 	uint32_t size = 0;
-	uint8_t *place_ptr;
-	uint32_t binsize;
+	uint8_t *binary_data;
+	uint32_t binary_size;
 
 	read_config_from_file(file_name, &data, &size);
 
-	place_ptr = data;
-	binsize = size;
+	binary_data = data;
+	binary_size = size;
 
 	if (!(*options).binary) {
-
 		if ((err = verify_xml_config(data, size)))
 			return LC_ERROR;
 
-		if ((err = find_config_binary_size(data, &binsize)))
-			return LC_ERROR;
-
-		/* We no longer need size, let it get munged... */
-		if ((err = find_config_binary_start(&place_ptr, &size)))
-			return LC_ERROR;
-
-		if (size < binsize)
+		if ((err = find_config_binary(data, size, &binary_data, &binary_size)))
 			return LC_ERROR;
 
 		if (!(*options).noweb)
-			post_preconfig(data);
+			post_preconfig(data, size);
 	}
 
 	/*
@@ -238,14 +230,14 @@
 	 * erase the flash (to 1) in order to write the flash.
 	 */
 	printf("Erasing Flash:       ");
-	if ((err = erase_config(binsize, cb, (void *)0))) {
+	if ((err = erase_config(binary_size, cb, (void *)0))) {
 		delete_blob(data);
 		return err;
 	}
 	printf("       done\n");
 
 	printf("Writing Config:      ");
-	if ((err = write_config_to_remote(place_ptr, binsize, cb,
+	if ((err = write_config_to_remote(binary_data, binary_size, cb,
 			(void *)1))) {
 		delete_blob(data);
 		return err;
@@ -253,7 +245,7 @@
 	printf("       done\n");
 
 	printf("Verifying Config:    ");
-	if ((err = verify_remote_config(place_ptr, binsize, cb, (void *)1))) {
+	if ((err = verify_remote_config(binary_data, binary_size, cb, (void *)1))) {
 		delete_blob(data);
 		return err;
 	}
@@ -261,7 +253,7 @@
 
 	if (!(*options).binary && !(*options).noweb) {
 		printf("Contacting website:  ");
-		if ((err = post_postconfig(data))) {
+		if ((err = post_postconfig(data, size))) {
 			delete_blob(data);
 			return err;
 		}
@@ -297,6 +289,7 @@
 {
 	int err;
 	uint8_t *firmware;
+	uint32_t firmware_size;
 	uint8_t *firmware_bin;
 
 	err = 0;
@@ -322,38 +315,48 @@
 	}
 
 	if ((err = read_firmware_from_file(file_name, &firmware,
-			(*options).binary))) {
+			&firmware_size, (*options).binary))) {
 		delete_blob(firmware);
 		return err;
 	}
 
-	if ((err = extract_firmware_binary(firmware, &firmware_bin))) {
-		delete_blob(firmware);
-		delete_blob(firmware_bin);
-		return err;
+	if ((*options).binary) {
+		firmware_bin = firmware;
+	} else {
+		if ((err = extract_firmware_binary(firmware, firmware_size, &firmware_bin))) {
+			delete_blob(firmware_bin);
+			delete_blob(firmware);
+			return err;
+		}
 	}
 
 	if (!(*options).direct) {
 		if ((err = prep_firmware())) {
 			printf("Failed to prepare remote for FW update\n");
+			if (firmware_bin != firmware) {
+				delete_blob(firmware_bin);
+			}
 			delete_blob(firmware);
-			delete_blob(firmware_bin);
 			return err;
 		}
 	}
 
 	printf("Invalidating Flash:  ");
 	if ((err = invalidate_flash())) {
+		if (firmware_bin != firmware) {
+			delete_blob(firmware_bin);
+		}
 		delete_blob(firmware);
-		delete_blob(firmware_bin);
 		return err;
 	}
 	printf("                     done\n");
 
 	printf("Erasing Flash:       ");
 	if ((err = erase_firmware((*options).direct, cb, (void *)0))) {
+		if (firmware_bin != firmware) {
+			delete_blob(firmware_bin);
+		}
 		delete_blob(firmware);
-		delete_blob(firmware_bin);
 		return err;
 	}
 	printf("       done\n");
@@ -361,13 +364,18 @@
 	printf("Writing firmware:    ");
 	if ((err = write_firmware_to_remote(firmware_bin, (*options).direct, cb,
 			cb_arg))) {
+		if (firmware_bin != firmware) {
+			delete_blob(firmware_bin);
+		}
 		delete_blob(firmware);
 		return err;
 	}
 	printf("       done\n");
 
 	/* Done with this... */
-	delete_blob(firmware_bin);
+	if (firmware_bin != firmware) {
+		delete_blob(firmware_bin);
+	}
 
 	if (!(*options).direct) {
 		if ((err = finish_firmware())) {
@@ -379,7 +387,7 @@
 
 	if (!(*options).binary && !(*options).noweb) {
 		printf("Contacting website:  ");
-		if ((err = post_postfirmware(firmware))) {
+		if ((err = post_postfirmware(firmware, firmware_size))) {
 			delete_blob(firmware);
 			return err;
 		}
Index: libconcord/libconcord.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.cpp,v
retrieving revision 1.11
diff -u -r1.11 libconcord.cpp
--- libconcord/libconcord.cpp	14 Mar 2008 23:09:36 -0000	1.11
+++ libconcord/libconcord.cpp	16 Mar 2008 20:05:11 -0000
@@ -313,10 +313,9 @@
 	return "Unknown error";
 }
 
-int delete_blob(uint8_t *ptr)
+void delete_blob(uint8_t *ptr)
 {
 	delete[] ptr;
-	return 1;
 }
 
 
@@ -425,21 +424,21 @@
 	return 0;
 }
 
-int post_preconfig(uint8_t *data)
+int post_preconfig(uint8_t *data, uint32_t size)
 {
-	Post(data, "POSTOPTIONS", ri, true);
+	Post(data, size, "POSTOPTIONS", ri, true);
 	return 0;
 }
 
-int post_postfirmware(uint8_t *data)
+int post_postfirmware(uint8_t *data, uint32_t size)
 {
-	Post(data, "COMPLETEPOSTOPTIONS", ri, false);
+	Post(data, size, "COMPLETEPOSTOPTIONS", ri, false);
 	return 0;
 }
 
-int post_postconfig(uint8_t *data)
+int post_postconfig(uint8_t *data, uint32_t size)
 {
-	Post(data, "COMPLETEPOSTOPTIONS", ri, true);
+	Post(data, size, "COMPLETEPOSTOPTIONS", ri, true);
 	return 0;
 }
 
@@ -455,12 +454,10 @@
 	}
 
 	const uint32_t size = file.getlength();
-	uint8_t * const buf = new uint8_t[size+1];
-	file.read(buf,size);
-	// Prevent GetTag() from going off the deep end
-	buf[size]=0;
+	uint8_t * const buf = new uint8_t[size];
+	file.read(buf, size);
 
-	Post(buf,"POSTOPTIONS", ri, true);
+	Post(buf, size, "POSTOPTIONS", ri, true);
 
 	if (file.close() != 0) {
 		return LC_ERROR_OS_FILE;
@@ -557,7 +554,7 @@
 	}
 
 	*size = file.getlength();
-	*out = new uint8_t[(*size) + 1];
+	*out = new uint8_t[*size];
 	file.read(*out, *size);
 
 	if (file.close() != 0) {
@@ -567,16 +564,10 @@
 		return LC_ERROR_OS_FILE;
 	}
 
-	/*
-	 * Prevent GetTag() from going off the deep end
-	 *   FIXME: Should probably be a \0, not a 0
-	 */
-	(*out)[*size] = 0;
-
 	return 0;
 }
 
-int write_config_to_file(uint8_t *in, char *file_name, uint32_t size,
+int write_config_to_file(uint8_t *in, uint32_t size, char *file_name,
 	int binary)
 {
 	binaryoutfile of;
@@ -626,46 +617,43 @@
 	return 0;
 }
 
-int verify_xml_config(uint8_t *data, uint32_t size)
+int verify_xml_config(uint8_t *config, uint32_t config_size)
 {
+	int err;
 
-	uint8_t *ptr = data;
 	string s;
-
-	GetTag("BINARYDATASIZE", ptr, &s);
-	uint32_t data_size = atoi(s.c_str());
-
-	GetTag("CHECKSUM", ptr, &s);
+	err = GetTag("CHECKSUM", config, config_size, 0, &s);
+	if (err != 0) {
+		return err;
+	}
 	const uint8_t checksum = atoi(s.c_str());
 
-	// Calculate size by moving pointer to end of XML
-	GetTag("/INFORMATION", ptr);
-	ptr += 2;
-	size -= (ptr - data);
-
 #ifdef _DEBUG
-	printf("reported data size %i\n", data_size);
-	printf("checksum %i\n", checksum);
-	printf("actual data size %i\n", size);
+	printf("reported checksum %i %02x\n", checksum, checksum);
 #endif
 
-	if (size != data_size) {
-#ifdef _DEBUG
-		printf("Data size mismatch %i %i\n", size, data_size);
-#endif
-		return LC_ERROR;
+	uint8_t * binary_ptr;
+	uint32_t binary_size;
+	err = find_config_binary(config, config_size,
+		&binary_ptr, &binary_size);
+	if (err != 0) {
+		return err;
 	}
 
 	// Calculate checksum
-	uint32_t u = size;
+	uint32_t u = binary_size;
 	uint8_t chk = 0x69;
-	uint8_t *pc = ptr;
+	uint8_t *pc = binary_ptr;
 	while (u--)
 		chk ^= *pc++;
 
+#ifdef _DEBUG
+	printf("actual checksum %i %02x\n", chk, chk);
+#endif
+
 	if (chk != checksum) {
 #ifdef _DEBUG
-		printf("Bad checksum %02X %02X\n",chk, checksum);
+		printf("Bad checksum\n");
 #endif
 		return LC_ERROR;
 	}
@@ -698,26 +686,35 @@
 	return 0;
 }
 
-int find_config_binary_size(uint8_t *ptr, uint32_t *size)
+int find_config_binary(uint8_t *config, uint32_t config_size,
+	uint8_t **binary_ptr, uint32_t *binary_size)
 {
-	string size_s;
-	int err = GetTag("BINARYDATASIZE", ptr, &size_s);
+	int err = GetTag("/INFORMATION", config, config_size, binary_ptr);
 	if (err == -1)
 		return LC_ERROR;
 
-	*size = (uint32_t)atoi(size_s.c_str());
-	return 0;
-}
+	*binary_ptr += 2;
+	*binary_size = config_size - (*binary_ptr - config);
 
-int find_config_binary_start(uint8_t **ptr, uint32_t *size)
-{
-	uint8_t *optr = *ptr;
-	int err = GetTag("/INFORMATION", *ptr);
+	string binary_tag_size_s;
+	err = GetTag("BINARYDATASIZE", config, config_size, 0,
+		&binary_tag_size_s);
 	if (err == -1)
 		return LC_ERROR;
 
-	*ptr += 2;
-	*size -= ((*ptr) - optr);
+        uint32_t binary_tag_size = (uint32_t)atoi(binary_tag_size_s.c_str());
+
+#ifdef _DEBUG
+	printf("actual data size %i\n", binary_size);
+	printf("reported data size %i\n", binary_tag_size);
+#endif
+
+	if (*binary_size != binary_tag_size) {
+#ifdef _DEBUG
+		printf("Data size mismatch\n");
+#endif
+		return LC_ERROR;
+	}
 
 	return 0;
 }
@@ -1093,19 +1090,31 @@
 	return 0;
 }
 
-int extract_firmware_binary(uint8_t *in, uint8_t **out)
+int extract_firmware_binary(uint8_t *xml, uint32_t xml_size, uint8_t **out)
 {
+	uint32_t o_size = FIRMWARE_SIZE;
+	*out = new uint8_t[o_size];
+	uint8_t *o = *out;
+
+	uint8_t *x = xml;
+	uint32_t x_size = xml_size;
+
 	string hex;
-	*out = new uint8_t[FIRMWARE_SIZE];
-	uint8_t *ptr = *out;
-	uint8_t *tmp = in;
-	while (GetTag("DATA", tmp, &hex) == 0) {
-		convert_to_binary(hex, ptr);
+	while (GetTag("DATA", x, x_size, &x, &hex) == 0) {
+		uint32_t hex_size = hex.length() / 2;
+		if (hex_size > o_size) {
+			return LC_ERROR;
+		}
+
+		convert_to_binary(hex, o);
+
+		x_size = xml_size - (x - xml);
+		o_size -= hex_size;
 	}
 	return 0;
 }
 	
-int read_firmware_from_file(char *file_name, uint8_t **out, int binary)
+int read_firmware_from_file(char *file_name, uint8_t **out, uint32_t *size, int binary)
 {
 	binaryinfile file;
 
@@ -1117,13 +1126,12 @@
 	}
 
 	if (binary) {
-		*out = new uint8_t[FIRMWARE_SIZE];
-		file.read(*out, FIRMWARE_SIZE);
+		*size = FIRMWARE_SIZE;
 	} else {
-		*out = new uint8_t[file.getlength() + 1];
-		file.read(*out, file.getlength());
-		(*out)[file.getlength()] = 0;
+		*size = file.getlength();
 	}
+	*out = new uint8_t[*size];
+	file.read(*out, *size);
 
 	if (file.close() != 0) {
 #ifdef _DEBUG
@@ -1140,26 +1148,32 @@
  */
 int learn_ir_commands(char *file_name, int post)
 {
+	int err;
+
 	if (file_name) {
 		binaryinfile file;
 		if (file.open(file_name)) {
 			return LC_ERROR_OS_FILE;
 		}
 		uint32_t size=file.getlength();
-		uint8_t * const x=new uint8_t[size+1];
+		uint8_t * const x=new uint8_t[size];
 		file.read(x,size);
 		if (file.close() != 0) {
 			return LC_ERROR_OS_FILE;
 		}
-		// Prevent GetTag() from going off the deep end
-		x[size]=0;
 
 		uint8_t *t=x;
 		string keyname;
 		do {
-			GetTag("KEY",t,&keyname);
-		} while (*t && keyname!="KeyName");
-		GetTag("VALUE",t,&keyname);
+			err = GetTag("KEY", t, size - (t - x), &t, &keyname);
+			if (err != 0) {
+				return err;
+			}
+		} while (keyname!="KeyName");
+		err = GetTag("VALUE",t,size,0,&keyname);
+		if (err != 0) {
+			return err;
+		}
 		printf("Key Name: %s\n",keyname.c_str());
 
 		string ls;
@@ -1167,8 +1181,7 @@
 		//printf("%s\n",ls.c_str());
 
 		if (post)
-			Post(x, "POSTOPTIONS", ri, true, &ls, &keyname);
-
+			Post(x, size, "POSTOPTIONS", ri, true, &ls, &keyname);
 	} else {
 		rmt->LearnIR();
 	}
Index: libconcord/libconcord.h
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.h,v
retrieving revision 1.8
diff -u -r1.8 libconcord.h
--- libconcord/libconcord.h	14 Mar 2008 09:23:01 -0000	1.8
+++ libconcord/libconcord.h	16 Mar 2008 20:05:11 -0000
@@ -140,8 +140,7 @@
  * to data that we allocate. You should then call this to clean that
  * data up when you are done with it.
  */
-int delete_blob(uint8_t *ptr);
-
+void delete_blob(uint8_t *ptr);
 
 /*
  * GENERAL REMOTE INTERACTIONS
@@ -187,19 +186,19 @@
  * Prior to updating the config, if you want to interact with the website
  * you have to send it some initial data. This does that. The data passed
  * in here is a pointer to the config data config block (with XML - this
- * should NOT be the pointer passed to find_binary_start().
+ * should NOT be the pointer result from find_binary_start().
  */
-int post_preconfig(uint8_t *data);
+int post_preconfig(uint8_t *data, uint32_t size);
 /*
  * After writing the config to the remote, this should be called to tell
  * the members.harmonyremote.com website that it was successful.
  */
-int post_postconfig(uint8_t *data);
+int post_postconfig(uint8_t *data, uint32_t size);
 /*
  * After writing a new firmware to the remote, this should be called to tell
  * the members.harmonyremote.com website that it was successful.
  */
-int post_postfirmware(uint8_t *data);
+int post_postfirmware(uint8_t *data, uint32_t size);
 /*
  * This sends the remote a command to tell it we're about to start
  * writing to it's flash area and that it shouldn't read from it.
@@ -251,14 +250,14 @@
  * binary is true, the XML will be constructed and written to the file
  * as well.
  */
-int write_config_to_file(uint8_t *in, char *file_name, uint32_t size,
+int write_config_to_file(uint8_t *in, uint32_t size, char *file_name,
 	int binary);
 /*
  * Given a blob of XML+binary config *in, calculate the checksums and compare
  * it to what's in the XML. Also compare the size reported from the actual
  * size.
  */
-int verify_xml_config(uint8_t *in, uint32_t size);
+int verify_xml_config(uint8_t *config, uint32_t config_size);
 /*
  * After doing a write_config_to_remote(), this should be called to verify
  * that config. The data will be compared to what's in *in.
@@ -271,18 +270,17 @@
  */
 int erase_config(uint32_t size, lc_callback cb, void *cb_arg);
 /*
- * Get the value from the BINARYSIZE tag in the XML.
- */
-int find_config_binary_size(uint8_t *ptr, uint32_t *size);
-/*
- * Pass in a pointer to an array holding the read in config object (for
- * example, one you might get from read_config_from_remote()), and it'll
- * adjust that pointer to the beginning of the binary portion (aka skip
- * past the XML portion).
- * Size should be the size of the ptr, and it will be modified to account
- * for the the change in *ptr.
+ * Determine the location of binary data within an XML configuration file.
+ * (aka skip past the XML portion).
+ *
+ * config and config size indicate the location and size of the configuration
+ * data (for example, what one you might get from read_config_from_remote()).
+ *
+ * *binary_ptr and *binary_size will set to the location and size of the
+ * binary portion of the configuration data.
  */
-int find_config_binary_start(uint8_t **ptr, uint32_t *size);
+int find_config_binary(uint8_t *config, uint32_t config_size,
+	uint8_t **binary_ptr, uint32_t *binary_size);
 
 /*
  * SAFEMODE FIRMWARE INTERACTIONS
@@ -375,13 +373,14 @@
  * you must use extract_firmware_binary() to get the binary data out
  * to pass to this function.
  */
-int read_firmware_from_file(char *file_name, uint8_t **out, int binary);
+int read_firmware_from_file(char *file_name, uint8_t **out, uint32_t *size,
+	int binary);
 /*
  * Extract the binary firmware from a file read in with
  * read_firmware_from_file(). Obviously this function isn't necessary in
  * binary mode.
  */
-int extract_firmware_binary(uint8_t *in, uint8_t **out);
+int extract_firmware_binary(uint8_t *xml, uint32_t xml_size, uint8_t **out);
 
 /*
  * IR-stuff. This stuff hasn't yet been cleaned up, you'll have to
@@ -393,5 +392,5 @@
 }
 #endif
 
-#endif // LIBCONCORD_H
+#endif /* LIBCONCORD_H */
 
Index: libconcord/web.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/web.cpp,v
retrieving revision 1.15
diff -u -r1.15 web.cpp
--- libconcord/web.cpp	14 Mar 2008 05:01:26 -0000	1.15
+++ libconcord/web.cpp	16 Mar 2008 20:05:11 -0000
@@ -149,77 +149,95 @@
 	return 0;
 }
 
-int GetTag(const char *find, uint8_t*& pc, string *s=NULL)
+int GetTag(const char *find, uint8_t* data, uint32_t data_size,
+	uint8_t **found, string *s=NULL)
 {
-	const size_t len = strlen(find);
-	do {
-		/*
-		 * Advance pointer until beginning of a tag, and then
-		 * one more.
-		 */
-		while(*pc != '<' && *pc++);
+	const size_t find_len = strlen(find);
+	uint8_t * search = data;
 
-		// Make sure we still have a valid pointer
-		if (!pc)
+	// Consume tags until there aren't any left
+	for (;;) {
+		// Loop searching for start of tag character
+		for (;;) {
+			if (*search == '<') {
+				break;
+			}
+			if (search - data >= data_size) {
+				return -1;
+			}
+			search++;
+		}
+		// Validate there's enough string left to hold the tag name
+		uint32_t needed_len = find_len + 2;
+		uint32_t left_len = data_size - (search - data);
+		if (left_len < needed_len) {
 			return -1;
-
+		}
+		// Point past <, at tag name
+		search++;
 		// Check to see if this is the tag we want
-		if (*++pc == *find && pc[len]=='>'
-		   && !strnicmp(find, reinterpret_cast<const char*>(pc), len)) {
-			pc += strlen(find) + 1;
+		if (search[find_len] == '>'
+		   && !strnicmp(find, reinterpret_cast<const char*>(search), find_len)) {
+			// Point past >, at tag content
+			search += find_len + 1;
+
+			if (found) {
+				*found = search;
+			}
 
 			/*
  			 * If a string pointer was passed in, then add the
  			 * contents of this entire tag to the string
  			 */
 			if (s) {
-				const uint8_t *p=pc;
 				*s = "";
 				/*
 				 * Here we keep adding chars until the next tag
 				 * which, in theory, should be the end-tag.
 				 */
-				while (*p != '<' && *p) {
-					*s+=*p;
-					++p;
+				while (*search && *search != '<') {
+					*s += *search;
+					search++;
+					if (search - data >= data_size) {
+						break;
+					}
 				}
 			}
 			return 0;
 		}
-		/*
-		 * Advance until we get to the closing bracket of the end-tag
-		 * we just found, and advance on more.
-		 */
-		while (*pc != '>' && *pc++);
-	/*
-	 * If we found it, we'd have returned above, so keep looping until
-	 * we do.
-	 */
-	} while(*pc++);
 
-	// GACK! We didn't find it.
-	return -1;
+		// Loop searching for end of tag character
+		for (;;) {
+			if (*search == '>') {
+				break;
+			}
+			if (search - data >= data_size) {
+				return -1;
+			}
+			search++;
+		}
+	}
 }
 
-int Post(uint8_t *xml, const char *root, TRemoteInfo &ri, bool has_userid,
-	string *learn_seq = NULL, string *learn_key = NULL)
+int Post(uint8_t *xml, uint32_t xml_size, const char *root, TRemoteInfo &ri,
+	bool has_userid, string *learn_seq = NULL, string *learn_key = NULL)
 {
 
 	uint8_t *x = xml;
 	int err;
-	if ((err = GetTag(root,x)))
+	if ((err = GetTag(root, x, xml_size - (x - xml), &x)))
 		return err;
 
 	string server, path, cookie, userid;
 
-	if ((err = GetTag("SERVER", x, &server)))
+	if ((err = GetTag("SERVER", x, xml_size - (x - xml), &x, &server)))
 		return err;
-	if ((err = GetTag("PATH", x, &path)))
+	if ((err = GetTag("PATH", x, xml_size - (x - xml), &x, &path)))
 		return err;
-	if ((err = GetTag("VALUE", x, &cookie)))
+	if ((err = GetTag("VALUE", x, xml_size - (x - xml), &x, &cookie)))
 		return err;
 	if (has_userid) {
-		if ((err = GetTag("VALUE", x, &userid)))
+		if ((err = GetTag("VALUE", x, xml_size - (x - xml), 0, &userid)))
 			return err;
 	}
 
Index: libconcord/web.h
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/web.h,v
retrieving revision 1.5
diff -u -r1.5 web.h
--- libconcord/web.h	14 Mar 2008 05:01:26 -0000	1.5
+++ libconcord/web.h	16 Mar 2008 20:05:11 -0000
@@ -20,8 +20,9 @@
 #ifndef WEB_H
 #define WEB_H
 
-int GetTag(const char *find, uint8_t*& pc, string *s=NULL);
-int Post(uint8_t *xml, const char *root, TRemoteInfo &ri, bool has_userid,
-	string *learn_seq=NULL, string *learn_key=NULL);
+int GetTag(const char *find, uint8_t* data, uint32_t data_size,
+	uint8_t **found, string *s=NULL);
+int Post(uint8_t *xml, uint32_t xml_size, const char *root, TRemoteInfo &ri,
+	bool has_userid, string *learn_seq=NULL, string *learn_key=NULL);
 
 #endif
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to