public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 ./WHATS_NEW lib/config/config.c lib/filte ...
@ 2008-03-12 16:03 agk
  0 siblings, 0 replies; 2+ messages in thread
From: agk @ 2008-03-12 16:03 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2008-03-12 16:03:22

Modified files:
	.              : WHATS_NEW 
	lib/config     : config.c 
	lib/filters    : filter-persistent.c 
	lib/format_text: export.c 
	lib/misc       : lvm-string.c lvm-string.h 

Log message:
	Escape double quotes and backslashes in external metadata and config data.
	Add functions for escaping double quotes in strings.
	Rename count_chars_len to count_chars.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.801&r2=1.802
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/config.c.diff?cvsroot=lvm2&r1=1.67&r2=1.68
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter-persistent.c.diff?cvsroot=lvm2&r1=1.35&r2=1.36
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/export.c.diff?cvsroot=lvm2&r1=1.61&r2=1.62
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-string.c.diff?cvsroot=lvm2&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-string.h.diff?cvsroot=lvm2&r1=1.17&r2=1.18

--- LVM2/WHATS_NEW	2008/03/10 18:51:27	1.801
+++ LVM2/WHATS_NEW	2008/03/12 16:03:21	1.802
@@ -1,5 +1,8 @@
 Version 2.02.34 -
 ===================================
+  Escape double quotes and backslashes in external metadata and config data.
+  Add functions for escaping double quotes in strings.
+  Rename count_chars_len to count_chars.
   Use return_0 in a couple more places.
   Correct a function name typo in _line_append error message.
   Include limits.h in clvmd so it compiles with newer headers.
--- LVM2/lib/config/config.c	2008/03/10 18:51:27	1.67
+++ LVM2/lib/config/config.c	2008/03/12 16:03:21	1.68
@@ -34,7 +34,8 @@
 enum {
 	TOK_INT,
 	TOK_FLOAT,
-	TOK_STRING,
+	TOK_STRING,		/* Single quotes */
+	TOK_STRING_ESCAPED,	/* Double quotes */
 	TOK_EQ,
 	TOK_SECTION_B,
 	TOK_SECTION_E,
@@ -401,9 +402,16 @@
 
 static int _write_value(struct output_line *outline, struct config_value *v)
 {
+	char *buf;
+
 	switch (v->type) {
 	case CFG_STRING:
-		line_append("\"%s\"", v->v.str);
+		if (!(buf = alloca(escaped_len(v->v.str)))) {
+			log_error("temporary stack allocation for a config "
+				  "string failed");
+			return 0;
+		}
+		line_append("\"%s\"", escape_double_quotes(buf, v->v.str));
 		break;
 
 	case CFG_FLOAT:
@@ -644,6 +652,17 @@
 		match(TOK_STRING);
 		break;
 
+	case TOK_STRING_ESCAPED:
+		v->type = CFG_STRING;
+
+		p->tb++, p->te--;	/* strip "'s */
+		if (!(v->v.str = _dup_tok(p)))
+			return_0;
+		unescape_double_quotes(v->v.str);
+		p->te++;
+		match(TOK_STRING_ESCAPED);
+		break;
+
 	default:
 		log_error("Parse error at byte %" PRIptrdiff_t " (line %d): expected a value",
 			  p->tb - p->fb + 1, p->line);
@@ -714,7 +733,7 @@
 		break;
 
 	case '"':
-		p->t = TOK_STRING;
+		p->t = TOK_STRING_ESCAPED;
 		p->te++;
 		while ((p->te != p->fe) && (*p->te) && (*p->te != '"')) {
 			if ((*p->te == '\\') && (p->te + 1 != p->fe) &&
@@ -1232,7 +1251,7 @@
 
 	c = _token_type_to_char(type);
 
-	return count_chars_len(str, len, c);
+	return count_chars(str, len, c);
 }
 
 /*
--- LVM2/lib/filters/filter-persistent.c	2008/01/30 13:59:58	1.35
+++ LVM2/lib/filters/filter-persistent.c	2008/03/12 16:03:21	1.36
@@ -18,6 +18,7 @@
 #include "dev-cache.h"
 #include "filter-persistent.h"
 #include "lvm-file.h"
+#include "lvm-string.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -142,6 +143,7 @@
 {
 	void *d;
 	int first = 1;
+	char *buf, *str;
 	struct dm_hash_node *n;
 
 	for (n = dm_hash_get_first(pf->devices); n;
@@ -158,7 +160,13 @@
 			first = 0;
 		}
 
-		fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
+		str = dm_hash_get_key(pf->devices, n);
+		if (!(buf = alloca(escaped_len(str)))) {
+			log_error("persistent filter device path stack "
+				  "allocation failed");
+			return;
+		}
+		fprintf(fp, "\t\t\"%s\"", escape_double_quotes(buf, str));
 	}
 
 	if (!first)
--- LVM2/lib/format_text/export.c	2008/01/30 13:59:59	1.61
+++ LVM2/lib/format_text/export.c	2008/03/12 16:03:22	1.62
@@ -296,6 +296,7 @@
 static int _print_header(struct formatter *f,
 			 const char *desc)
 {
+	char *buf;
 	time_t t;
 
 	t = time(NULL);
@@ -305,7 +306,12 @@
 	outf(f, FORMAT_VERSION_FIELD " = %d", FORMAT_VERSION_VALUE);
 	outnl(f);
 
-	outf(f, "description = \"%s\"", desc);
+	if (!(buf = alloca(escaped_len(desc)))) {
+		log_error("temporary stack allocation for description"
+			  "string failed");
+		return 0;
+	}
+	outf(f, "description = \"%s\"", escape_double_quotes(buf, desc));
 	outnl(f);
 	outf(f, "creation_host = \"%s\"\t# %s %s %s %s %s", _utsname.nodename,
 	     _utsname.sysname, _utsname.nodename, _utsname.release,
@@ -370,6 +376,7 @@
 	struct pv_list *pvl;
 	struct physical_volume *pv;
 	char buffer[4096];
+	char *buf;
 	const char *name;
 
 	outf(f, "physical_volumes {");
@@ -389,7 +396,15 @@
 			return_0;
 
 		outf(f, "id = \"%s\"", buffer);
-		if (!out_hint(f, "device = \"%s\"", pv_dev_name(pv)))
+
+		if (!(buf = alloca(escaped_len(pv_dev_name(pv))))) {
+			log_error("temporary stack allocation for device name"
+				  "string failed");
+			return 0;
+		}
+
+		if (!out_hint(f, "device = \"%s\"",
+			      escape_double_quotes(buf, pv_dev_name(pv))))
 			return_0;
 		outnl(f);
 
--- LVM2/lib/misc/lvm-string.c	2008/01/30 14:00:00	1.16
+++ LVM2/lib/misc/lvm-string.c	2008/03/12 16:03:22	1.17
@@ -39,16 +39,16 @@
  * Count occurences of 'c' in 'str' until we reach a null char.
  *
  * Returns:
- *  len - incremented for each char we encounter, whether 'c' or not.
- *  count - number of occurrences of 'c'
+ *  len - incremented for each char we encounter.
+ *  count - number of occurrences of 'c' and 'c2'.
  */
-void count_chars(const char *str, size_t *len, int *count,
-		 const int c)
+static void _count_chars(const char *str, size_t *len, int *count,
+			 const int c1, const int c2)
 {
 	const char *ptr;
 
 	for (ptr = str; *ptr; ptr++, (*len)++)
-		if (*ptr == c)
+		if (*ptr == c1 || *ptr == c2)
 			(*count)++;
 }
 
@@ -58,7 +58,7 @@
  * Returns:
  *   Number of occurrences of 'c'
  */
-unsigned count_chars_len(const char *str, size_t len, const int c)
+unsigned count_chars(const char *str, size_t len, const int c)
 {
 	size_t i;
 	unsigned count = 0;
@@ -71,19 +71,64 @@
 }
 
 /*
- * Copies a string, quoting hyphens with hyphens.
+ * Length of string after escaping double quotes and backslashes.
  */
-static void _quote_hyphens(char **out, const char *src)
+size_t escaped_len(const char *str)
+{
+	size_t len = 1;
+	int count = 0;
+
+	_count_chars(str, &len, &count, '\"', '\\');
+
+	return count + len;
+}
+
+/*
+ * Copies a string, quoting orig_char with quote_char.
+ * Optionally also quote quote_char.
+ */
+static void _quote_characters(char **out, const char *src,
+			      const int orig_char, const int quote_char,
+			      int quote_quote_char)
 {
 	while (*src) {
-		if (*src == '-')
-			*(*out)++ = '-';
+		if (*src == orig_char ||
+		    (*src == quote_char && quote_quote_char))
+			*(*out)++ = quote_char;
 
 		*(*out)++ = *src++;
 	}
 }
 
 /*
+ * Unquote orig_char in string.
+ * Also unquote quote_char.
+ */
+static void _unquote_characters(char *src, const int orig_char,
+				const int quote_char)
+{
+	char *out = src;
+
+	while (*src) {
+		if (*src == quote_char &&
+		    (*(src + 1) == orig_char || *(src + 1) == quote_char))
+			src++;
+
+		*out++ = *src++;
+	}
+
+	*out = '\0';
+}
+
+/*
+ * Copies a string, quoting hyphens with hyphens.
+ */
+static void _quote_hyphens(char **out, const char *src)
+{
+	return _quote_characters(out, src, '-', '-', 0);
+}
+
+/*
  * <vg>-<lv>-<layer> or if !layer just <vg>-<lv>.
  */
 char *build_dm_name(struct dm_pool *mem, const char *vgname,
@@ -93,11 +138,11 @@
 	int hyphens = 1;
 	char *r, *out;
 
-	count_chars(vgname, &len, &hyphens, '-');
-	count_chars(lvname, &len, &hyphens, '-');
+	_count_chars(vgname, &len, &hyphens, '-', 0);
+	_count_chars(lvname, &len, &hyphens, '-', 0);
 
 	if (layer && *layer) {
-		count_chars(layer, &len, &hyphens, '-');
+		_count_chars(layer, &len, &hyphens, '-', 0);
 		hyphens++;
 	}
 
@@ -126,6 +171,27 @@
 }
 
 /*
+ * Copies a string, quoting double quotes with backslashes.
+ */
+char *escape_double_quotes(char *out, const char *src)
+{
+	char *buf = out;
+
+	_quote_characters(&buf, src, '\"', '\\', 1);
+	*buf = '\0';
+
+	return out;
+}
+
+/*
+ * Undo quoting in situ.
+ */
+void unescape_double_quotes(char *src)
+{
+	_unquote_characters(src, '\"', '\\');
+}
+
+/*
  * Device layer names are all of the form <vg>-<lv>-<layer>, any
  * other hyphens that appear in these names are quoted with yet
  * another hyphen.  The top layer of any device has no layer
--- LVM2/lib/misc/lvm-string.h	2007/08/22 14:38:17	1.17
+++ LVM2/lib/misc/lvm-string.h	2008/03/12 16:03:22	1.18
@@ -31,8 +31,27 @@
 
 int validate_name(const char *n);
 
-void count_chars(const char *str, size_t *len, int *count,
-		 const int c);
-unsigned count_chars_len(const char *str, size_t len, const int c);
+/*
+ * Returns number of occurrences of c in first len characters of str.
+ */
+unsigned count_chars(const char *str, size_t len, const int c);
+
+/*
+ * Returns what length of escaped string would be including terminating NUL.
+ */
+size_t escaped_len(const char *str);
+
+/*
+ * Copies a string from src to out. 
+ * Double quotation marks and backslashes are quoted with a backslash.
+ * Caller must ensure *out has enough space - see escaped_len().
+ * Returns *out.
+ */
+char *escape_double_quotes(char *out, const char *src);
+
+/*
+ * Removes quoting of double quotation marks and backslashes in situ.
+ */
+void unescape_double_quotes(char *src);
 
 #endif


^ permalink raw reply	[flat|nested] 2+ messages in thread

* LVM2 ./WHATS_NEW lib/config/config.c lib/filte ...
@ 2007-07-24 17:48 meyering
  0 siblings, 0 replies; 2+ messages in thread
From: meyering @ 2007-07-24 17:48 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	meyering@sourceware.org	2007-07-24 17:48:08

Modified files:
	.              : WHATS_NEW 
	lib/config     : config.c 
	lib/filters    : filter-persistent.c 
	lib/format_text: archive.c format-text.c 
	lib/log        : log.c 
	lib/misc       : lvm-file.c lvm-file.h 

Log message:
	Detect stream write failure reliably; new fn: lvm_fclose; use dm_fclose
	* lib/misc/lvm-file.c (lvm_fclose): New function.
	* lib/misc/lvm-file.h (lvm_fclose): Declare it.
	* lib/config/config.c (write_config_file): Use the new function to detect
	and diagnose unlikely write failure.
	* lib/filters/filter-persistent.c (persistent_filter_dump): Likewise.
	* lib/format_text/archive.c (archive_vg): Likewise.
	* lib/format_text/format-text.c (_vg_write_file): Likewise.
	* lib/log/log.c (fin_log): Similar, but use dm_fclose directly.
	Include "\n" at end of each fprintf format string.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.670&r2=1.671
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/config.c.diff?cvsroot=lvm2&r1=1.62&r2=1.63
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter-persistent.c.diff?cvsroot=lvm2&r1=1.31&r2=1.32
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/archive.c.diff?cvsroot=lvm2&r1=1.27&r2=1.28
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.77&r2=1.78
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/log/log.c.diff?cvsroot=lvm2&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.c.diff?cvsroot=lvm2&r1=1.20&r2=1.21
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.h.diff?cvsroot=lvm2&r1=1.9&r2=1.10

--- LVM2/WHATS_NEW	2007/07/24 15:35:11	1.670
+++ LVM2/WHATS_NEW	2007/07/24 17:48:07	1.671
@@ -1,5 +1,6 @@
 Version 2.02.28 -
 ================================
+  Detect stream write failure reliably; new fn: lvm_fclose; use dm_fclose
   Fix clvmd if compiled with gulm support. (2.02.26)
   Trivial fix to lvdisplay man page.
   Add vg_lock_and_read() external library function.
--- LVM2/lib/config/config.c	2007/07/20 15:38:19	1.62
+++ LVM2/lib/config/config.c	2007/07/24 17:48:07	1.63
@@ -20,6 +20,7 @@
 #include "str_list.h"
 #include "toolcontext.h"
 #include "lvm-string.h"
+#include "lvm-file.h"
 
 #include <sys/stat.h>
 #include <sys/mman.h>
@@ -520,8 +521,8 @@
 		argv++;
 	}
 
-	if (outline.fp && fclose(outline.fp)) {
-		log_sys_error("fclose", file);
+	if (outline.fp && lvm_fclose(outline.fp, file)) {
+		stack;
 		r = 0;
 	}
 
--- LVM2/lib/filters/filter-persistent.c	2007/07/20 15:22:45	1.31
+++ LVM2/lib/filters/filter-persistent.c	2007/07/24 17:48:08	1.32
@@ -239,10 +239,8 @@
 	/* _write_array(pf, fp, "invalid_devices", PF_BAD_DEVICE); */
 
 	fprintf(fp, "}\n");
-	if (fclose(fp)) {
-		log_sys_error("fclose", tmp_file);
-		goto out;
-	}
+	if (lvm_fclose(fp, tmp_file))
+		goto_out;
 
 	if (rename(tmp_file, pf->file))
 		log_error("%s: rename to %s failed: %s", tmp_file, pf->file,
--- LVM2/lib/format_text/archive.c	2007/07/02 11:17:21	1.27
+++ LVM2/lib/format_text/archive.c	2007/07/24 17:48:08	1.28
@@ -261,11 +261,8 @@
 		return 0;
 	}
 
-	if (fclose(fp)) {
-		log_sys_error("fclose", temp_file);
-		/* Leave file behind as evidence of failure */
-		return 0;
-	}
+	if (lvm_fclose(fp, temp_file))
+		return_0; /* Leave file behind as evidence of failure */
 
 	/*
 	 * Now we want to rename this file to <vg>_index.vg.
--- LVM2/lib/format_text/format-text.c	2007/07/02 11:17:21	1.77
+++ LVM2/lib/format_text/format-text.c	2007/07/24 17:48:08	1.78
@@ -892,10 +892,8 @@
 		return 0;
 	}
 
-	if (fclose(fp)) {
-		log_sys_error("fclose", tc->path_edit);
-		return 0;
-	}
+	if (lvm_fclose(fp, tc->path_edit))
+		return_0;
 
 	if (rename(temp_file, tc->path_edit)) {
 		log_debug("Renaming %s to %s", temp_file, tc->path_edit);
--- LVM2/lib/log/log.c	2007/06/28 17:33:44	1.39
+++ LVM2/lib/log/log.c	2007/07/24 17:48:08	1.40
@@ -17,6 +17,7 @@
 #include "device.h"
 #include "memlock.h"
 #include "lvm-string.h"
+#include "lvm-file.h"
 #include "defaults.h"
 
 #include <stdarg.h>
@@ -121,8 +122,14 @@
 	}
 
 	if (_log_to_file) {
-		if (fclose(_log_file))
-			fprintf(stderr, "fclose() on log file failed: %s", strerror(errno));
+		if (dm_fclose(_log_file)) {
+			if (errno)
+			      fprintf(stderr, "failed to write log file: %s\n",
+				      strerror(errno));
+			else
+			      fprintf(stderr, "failed to write log file\n");
+
+		}
 		_log_to_file = 0;
 	}
 }
--- LVM2/lib/misc/lvm-file.c	2007/04/26 16:44:59	1.20
+++ LVM2/lib/misc/lvm-file.c	2007/07/24 17:48:08	1.21
@@ -321,3 +321,13 @@
 			  strerror(errno));
 }
 
+int lvm_fclose(FILE *fp, const char *filename)
+{
+	if (!dm_fclose(fp))
+		return 0;
+	if (errno == 0)
+		log_error("%s: write error", filename);
+	else
+		log_sys_error("write error", filename);
+	return EOF;
+}
--- LVM2/lib/misc/lvm-file.h	2007/07/20 15:22:46	1.9
+++ LVM2/lib/misc/lvm-file.h	2007/07/24 17:48:08	1.10
@@ -56,4 +56,13 @@
   ((buf1).st_ino == (buf2).st_ino && \
    (buf1).st_dev == (buf2).st_dev)
 
+/*
+ * Close the specified stream, taking care to detect and diagnose any write
+ * error.  If there is an error, use the supplied file name in a diagnostic
+ * that is reported via log_error or log_sys_error, as appropriate.
+ * Use this function to close a stream when you've written data to it via
+ * unchecked fprintf, fputc, etc. calls.  Return 0 on success, EOF on failure.
+ */
+int lvm_fclose(FILE *fp, const char *filename);
+
 #endif


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-03-12 16:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-12 16:03 LVM2 ./WHATS_NEW lib/config/config.c lib/filte agk
  -- strict thread matches above, loose matches on Subject: below --
2007-07-24 17:48 meyering

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).