[PATCH wayland 3/3] Validate the protocol xml during scanning

Pekka Paalanen ppaalanen at gmail.com
Mon Nov 9 01:44:49 PST 2015


On Mon,  9 Nov 2015 14:15:01 +1000
Peter Hutterer <peter.hutterer at who-t.net> wrote:

> Embed the wayland.dtd protocol data into the scanner binary so we can validate
> external protocol files without requiring makefile changes. Hat-tip to Pekka
> Paalanen for the embedding trick.
> The embedding trick doesn't work well if the to-be-embedded file is in a
> different location than the source file, so copy/link it during configure and
> then build it in from the local directory.
> 
> The current expat parser is not a validating parser, moving scanner.c to
> another parser has the risk of breaking compatibility. This patch adds libxml2
> as extra (optional) dependency, but that also requires parsing the input
> twice.
> 
> If the protocol fails validation a warning is printed but no error is returned
> otherwise.
> 
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>  Makefile.am   |  9 ++++++--
>  configure.ac  | 12 ++++++++++
>  src/dtddata.S | 40 ++++++++++++++++++++++++++++++++++
>  src/scanner.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 129 insertions(+), 2 deletions(-)
>  create mode 100644 src/dtddata.S

> diff --git a/Makefile.am b/Makefile.am
> index 9114d98..e2e52ed 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -24,10 +24,15 @@ pkgconfig_DATA =
>  
>  bin_PROGRAMS = wayland-scanner
>  wayland_scanner_SOURCES = src/scanner.c
> -wayland_scanner_CFLAGS = $(EXPAT_CFLAGS) $(AM_CFLAGS)
> -wayland_scanner_LDADD = $(EXPAT_LIBS) libwayland-util.la
> +wayland_scanner_CFLAGS = $(EXPAT_CFLAGS) $(LIBXML_CFLAGS) $(AM_CFLAGS)
> +wayland_scanner_LDADD = $(EXPAT_LIBS) $(LIBXML_LIBS) libwayland-util.la src/dtddata.o
>  pkgconfig_DATA += src/wayland-scanner.pc
>  
> +src/dtddata.o: protocol/wayland.dtd

Hi Peter,

I think the paths here may need some fixing. 'make distcheck' fails on

  CCLD     wayland-scanner
gcc: error: src/dtddata.o: No such file or directory
Makefile:1447: recipe for target 'wayland-scanner' failed

> +
> +%.o: %.S
> +	$(AM_V_GEN)$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c -o $@ $<
> +
>  if USE_HOST_SCANNER
>  wayland_scanner = wayland-scanner
>  else

> diff --git a/src/scanner.c b/src/scanner.c
> index f456aa5..45d60c1 100644
> --- a/src/scanner.c
> +++ b/src/scanner.c
> @@ -25,6 +25,8 @@
>   * SOFTWARE.
>   */
>  
> +#include "config.h"
> +
>  #include <stdbool.h>
>  #include <stdio.h>
>  #include <stdarg.h>
> @@ -34,9 +36,18 @@
>  #include <expat.h>
>  #include <getopt.h>
>  #include <limits.h>
> +#include <unistd.h>
> +
> +#if HAVE_LIBXML
> +#include <libxml/parser.h>
> +#endif
>  
>  #include "wayland-util.h"
>  
> +/* Embedded wayland.dtd file, see dtddata.S */
> +extern char DTD_DATA_begin;
> +extern int DTD_DATA_len;
> +
>  enum side {
>  	CLIENT,
>  	SERVER,
> @@ -59,6 +70,56 @@ usage(int ret)
>  	exit(ret);
>  }
>  
> +static bool
> +is_dtd_valid(void)
> +{
> +	bool rc = true;
> +#if HAVE_LIBXML
> +	xmlParserCtxtPtr ctx = NULL;
> +	xmlDocPtr doc = NULL;
> +	xmlDtdPtr dtd = NULL;
> +	xmlValidCtxtPtr	dtdctx;
> +	xmlParserInputBufferPtr	buffer;
> +
> +	dtdctx = xmlNewValidCtxt();
> +	ctx = xmlNewParserCtxt();
> +	if (!ctx || !dtdctx)
> +		abort();
> +
> +	buffer = xmlParserInputBufferCreateMem(&DTD_DATA_begin,
> +					       DTD_DATA_len,
> +					       XML_CHAR_ENCODING_UTF8);
> +	if (!buffer) {
> +		fprintf(stderr, "Failed to init buffer for DTD.\n");
> +		abort();
> +	}
> +
> +	dtd = xmlIOParseDTD(NULL, buffer, XML_CHAR_ENCODING_UTF8);
> +	if (!dtd) {
> +		fprintf(stderr, "Failed to parse DTD.\n");
> +		abort();
> +	}
> +
> +	doc = xmlCtxtReadFd(ctx, STDIN_FILENO, "protocol", NULL, 0);

Using STDIN_FILENO misses an alternative use case of wayland-scanner,
where you pass both input and output file names as arguments.

See particularly the variable 'input' in main().

> +	if (!doc) {
> +		fprintf(stderr, "Failed to read XML\n");
> +		abort();
> +	}
> +
> +	rc = xmlValidateDtd(dtdctx, doc, dtd);
> +	xmlFreeDoc(doc);
> +	xmlFreeParserCtxt(ctx);
> +	xmlFreeValidCtxt(dtdctx);
> +	/* xmlIOParseDTD consumes buffer */
> +
> +	if (lseek(STDIN_FILENO, 0, SEEK_SET) != 0) {
> +		fprintf(stderr, "Failed to reset fd, output would be garbage.\n");
> +		abort();
> +	}
> +#endif
> +	return rc;
> +}

Otherwise the patch looks good to me.


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20151109/bd1aae61/attachment.sig>


More information about the wayland-devel mailing list