Fix: sessiond: ODR violation results in memory corruption
[lttng-tools.git] / tests / utils / xml-utils / validate_xml.cpp
CommitLineData
68270f0f 1/*
4b2b86f2 2 * Copyright (C) 2014 EfficiOS Inc.
68270f0f 3 *
9d16b343 4 * SPDX-License-Identifier: LGPL-2.1-only
68270f0f 5 *
68270f0f
JRJ
6 */
7
8 /*
9 * This script validate and xml from an xsd.
10 * argv[1] Path of the xsd
11 * argv[2] Path to the XML to be validated
12 */
13
68270f0f
JRJ
14#include <ctype.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <inttypes.h>
19#include <dirent.h>
20#include <unistd.h>
21#include <sys/types.h>
22#include <sys/stat.h>
23
24#include <libxml/xmlschemas.h>
25#include <libxml/parser.h>
26
27#include <lttng/lttng-error.h>
c9e313bc 28#include <common/macros.hpp>
d22ad5f8 29
f1494934 30namespace {
68270f0f
JRJ
31struct validation_ctx {
32 xmlSchemaParserCtxtPtr parser_ctx;
33 xmlSchemaPtr schema;
34 xmlSchemaValidCtxtPtr schema_validation_ctx;
35};
f1494934 36} /* namespace */
68270f0f
JRJ
37
38enum command_err_code {
39 CMD_SUCCESS = 0,
40 CMD_ERROR
41};
42
d22ad5f8 43static ATTR_FORMAT_PRINTF(2, 3)
f46376a1
MJ
44void xml_error_handler(void *ctx __attribute__((unused)),
45 const char *format, ...)
68270f0f
JRJ
46{
47 char *err_msg;
48 va_list args;
49 int ret;
50
51 va_start(args, format);
52 ret = vasprintf(&err_msg, format, args);
53 va_end(args);
54 if (ret == -1) {
55 fprintf(stderr, "ERR: %s\n",
56 "String allocation failed in xml error handle");
57 return;
58 }
59
60 fprintf(stderr, "XML Error: %s\n", err_msg);
61 free(err_msg);
62}
63
64static
65void fini_validation_ctx(
66 struct validation_ctx *ctx)
67{
68 if (ctx->parser_ctx) {
69 xmlSchemaFreeParserCtxt(ctx->parser_ctx);
70 }
71
72 if (ctx->schema) {
73 xmlSchemaFree(ctx->schema);
74 }
75
76 if (ctx->schema_validation_ctx) {
77 xmlSchemaFreeValidCtxt(ctx->schema_validation_ctx);
78 }
79
80 memset(ctx, 0, sizeof(struct validation_ctx));
81}
82
83static
84int init_validation_ctx(
85 struct validation_ctx *ctx, char *xsd_path)
86{
87 int ret;
88
89 if (!xsd_path) {
90 ret = -LTTNG_ERR_NOMEM;
91 goto end;
92 }
93
94 ctx->parser_ctx = xmlSchemaNewParserCtxt(xsd_path);
95 if (!ctx->parser_ctx) {
96 ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
97 goto end;
98 }
99 xmlSchemaSetParserErrors(ctx->parser_ctx, xml_error_handler,
100 xml_error_handler, NULL);
101
102 ctx->schema = xmlSchemaParse(ctx->parser_ctx);
103 if (!ctx->schema) {
104 ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
105 goto end;
106 }
107
108 ctx->schema_validation_ctx = xmlSchemaNewValidCtxt(ctx->schema);
109 if (!ctx->schema_validation_ctx) {
110 ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
111 goto end;
112 }
113
114 xmlSchemaSetValidErrors(ctx->schema_validation_ctx, xml_error_handler,
115 xml_error_handler, NULL);
116 ret = 0;
117
118end:
119 if (ret) {
120 fini_validation_ctx(ctx);
121 }
122 return ret;
123}
124
125static int validate_xml(const char *xml_file_path, struct validation_ctx *ctx)
126{
127 int ret;
128 xmlDocPtr doc = NULL;
129
a0377dfe
FD
130 LTTNG_ASSERT(xml_file_path);
131 LTTNG_ASSERT(ctx);
68270f0f
JRJ
132
133 /* Open the document */
134 doc = xmlParseFile(xml_file_path);
135 if (!doc) {
136 ret = LTTNG_ERR_MI_IO_FAIL;
137 goto end;
138 }
139
140 /* Validate against the validation ctx (xsd) */
141 ret = xmlSchemaValidateDoc(ctx->schema_validation_ctx, doc);
142 if (ret) {
143 fprintf(stderr, "ERR: %s\n", "XML is not valid againt provided XSD");
144 ret = CMD_ERROR;
145 goto end;
146 }
147
148 ret = CMD_SUCCESS;
149end:
21699d0f
JG
150 if (doc) {
151 xmlFreeDoc(doc);
152 }
68270f0f 153 return ret;
68270f0f 154}
21699d0f 155
f46376a1 156int main(int argc, char **argv)
68270f0f
JRJ
157{
158 int ret;
1c9a0b0e 159 struct validation_ctx ctx = {};
68270f0f
JRJ
160
161 /* Check if we have all argument */
162 if (argc < 3) {
163 fprintf(stderr, "ERR: %s\n", "Missing arguments");
164 ret = CMD_ERROR;
165 goto end;
166 }
167
168 /* Check if xsd file exist */
169 ret = access(argv[1], F_OK);
170 if (ret < 0) {
171 fprintf(stderr, "ERR: %s\n", "Xsd path not valid");
172 goto end;
173 }
174
175 /* Check if xml to validate exist */
176 ret = access(argv[2], F_OK);
177 if (ret < 0) {
178 fprintf(stderr, "ERR: %s\n", "XML path not valid");
179 goto end;
180 }
181
182 /* initialize the validation ctx */
183 ret = init_validation_ctx(&ctx, argv[1]);
184 if (ret) {
185 goto end;
186 }
187
188 ret = validate_xml(argv[2], &ctx);
189
190 fini_validation_ctx(&ctx);
191
192end:
193 return ret;
194}
This page took 0.049289 seconds and 4 git commands to generate.