Print this page
NEX-2207 mountd and rpcbind should use libumem(3lib)
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-2191 reverse resolve does not work in /usr/lib/krb5/klookup
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-2209 libnvpair produces bad JSON format (lint)
NEX-2209 libnvpair produces bad JSON format
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libnvpair/nvpair_json.c
+++ new/usr/src/lib/libnvpair/nvpair_json.c
1 1 /*
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11 /*
12 + * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
12 13 * Copyright (c) 2014, Joyent, Inc.
13 14 */
14 15
15 16 #include <stdio.h>
16 17 #include <stdlib.h>
17 18 #include <strings.h>
18 19 #include <wchar.h>
19 20 #include <sys/debug.h>
20 21
21 22 #include "libnvpair.h"
22 23
23 24 #define FPRINTF(fp, ...) \
24 25 do { \
25 26 if (fprintf(fp, __VA_ARGS__) < 0) \
26 27 return (-1); \
27 28 } while (0)
28 29
29 30 /*
30 31 * When formatting a string for JSON output we must escape certain characters,
31 32 * as described in RFC4627. This applies to both member names and
32 33 * DATA_TYPE_STRING values.
33 34 *
34 35 * This function will only operate correctly if the following conditions are
35 36 * met:
36 37 *
37 38 * 1. The input String is encoded in the current locale.
38 39 *
39 40 * 2. The current locale includes the Basic Multilingual Plane (plane 0)
40 41 * as defined in the Unicode standard.
41 42 *
42 43 * The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all
43 44 * representable Unicode characters included in their escaped numeric form.
44 45 */
45 46 static int
46 47 nvlist_print_json_string(FILE *fp, const char *input)
47 48 {
48 49 mbstate_t mbr;
49 50 wchar_t c;
50 51 size_t sz;
51 52
52 53 bzero(&mbr, sizeof (mbr));
53 54
54 55 FPRINTF(fp, "\"");
55 56 while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) {
56 57 switch (c) {
57 58 case '"':
58 59 FPRINTF(fp, "\\\"");
59 60 break;
60 61 case '\n':
61 62 FPRINTF(fp, "\\n");
62 63 break;
63 64 case '\r':
64 65 FPRINTF(fp, "\\r");
65 66 break;
66 67 case '\\':
67 68 FPRINTF(fp, "\\\\");
68 69 break;
69 70 case '\f':
70 71 FPRINTF(fp, "\\f");
71 72 break;
72 73 case '\t':
73 74 FPRINTF(fp, "\\t");
74 75 break;
75 76 case '\b':
76 77 FPRINTF(fp, "\\b");
77 78 break;
78 79 default:
79 80 if ((c >= 0x00 && c <= 0x1f) ||
80 81 (c > 0x7f && c <= 0xffff)) {
81 82 /*
82 83 * Render both Control Characters and Unicode
83 84 * characters in the Basic Multilingual Plane
84 85 * as JSON-escaped multibyte characters.
85 86 */
86 87 FPRINTF(fp, "\\u%04x", (int)(0xffff & c));
87 88 } else if (c >= 0x20 && c <= 0x7f) {
88 89 /*
89 90 * Render other 7-bit ASCII characters directly
90 91 * and drop other, unrepresentable characters.
91 92 */
92 93 FPRINTF(fp, "%c", (int)(0xff & c));
93 94 }
94 95 break;
95 96 }
96 97 input += sz;
97 98 }
98 99
99 100 if (sz == (size_t)-1 || sz == (size_t)-2) {
100 101 /*
101 102 * We last read an invalid multibyte character sequence,
102 103 * so return an error.
103 104 */
104 105 return (-1);
105 106 }
106 107
107 108 FPRINTF(fp, "\"");
108 109 return (0);
109 110 }
110 111
111 112 /*
112 113 * Dump a JSON-formatted representation of an nvlist to the provided FILE *.
113 114 * This routine does not output any new-lines or additional whitespace other
114 115 * than that contained in strings, nor does it call fflush(3C).
115 116 */
116 117 int
117 118 nvlist_print_json(FILE *fp, nvlist_t *nvl)
118 119 {
119 120 nvpair_t *curr;
120 121 boolean_t first = B_TRUE;
121 122
122 123 FPRINTF(fp, "{");
123 124
124 125 for (curr = nvlist_next_nvpair(nvl, NULL); curr;
125 126 curr = nvlist_next_nvpair(nvl, curr)) {
126 127 data_type_t type = nvpair_type(curr);
127 128
128 129 if (!first)
129 130 FPRINTF(fp, ",");
130 131 else
131 132 first = B_FALSE;
132 133
133 134 if (nvlist_print_json_string(fp, nvpair_name(curr)) == -1)
134 135 return (-1);
135 136 FPRINTF(fp, ":");
136 137
137 138 switch (type) {
138 139 case DATA_TYPE_STRING: {
139 140 char *string = fnvpair_value_string(curr);
140 141 if (nvlist_print_json_string(fp, string) == -1)
141 142 return (-1);
142 143 break;
143 144 }
144 145
145 146 case DATA_TYPE_BOOLEAN: {
146 147 FPRINTF(fp, "true");
147 148 break;
148 149 }
149 150
150 151 case DATA_TYPE_BOOLEAN_VALUE: {
151 152 FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) ==
152 153 B_TRUE ? "true" : "false");
153 154 break;
154 155 }
155 156
156 157 case DATA_TYPE_BYTE: {
157 158 FPRINTF(fp, "%hhu", fnvpair_value_byte(curr));
158 159 break;
159 160 }
160 161
161 162 case DATA_TYPE_INT8: {
162 163 FPRINTF(fp, "%hhd", fnvpair_value_int8(curr));
163 164 break;
164 165 }
165 166
166 167 case DATA_TYPE_UINT8: {
167 168 FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr));
168 169 break;
169 170 }
170 171
171 172 case DATA_TYPE_INT16: {
172 173 FPRINTF(fp, "%hd", fnvpair_value_int16(curr));
173 174 break;
174 175 }
175 176
176 177 case DATA_TYPE_UINT16: {
177 178 FPRINTF(fp, "%hu", fnvpair_value_uint16(curr));
178 179 break;
179 180 }
180 181
181 182 case DATA_TYPE_INT32: {
182 183 FPRINTF(fp, "%d", fnvpair_value_int32(curr));
183 184 break;
184 185 }
185 186
186 187 case DATA_TYPE_UINT32: {
187 188 FPRINTF(fp, "%u", fnvpair_value_uint32(curr));
188 189 break;
189 190 }
190 191
191 192 case DATA_TYPE_INT64: {
192 193 FPRINTF(fp, "%lld",
193 194 (long long)fnvpair_value_int64(curr));
194 195 break;
195 196 }
196 197
197 198 case DATA_TYPE_UINT64: {
198 199 FPRINTF(fp, "%llu",
199 200 (unsigned long long)fnvpair_value_uint64(curr));
200 201 break;
201 202 }
202 203
203 204 case DATA_TYPE_HRTIME: {
204 205 hrtime_t val;
205 206 VERIFY0(nvpair_value_hrtime(curr, &val));
206 207 FPRINTF(fp, "%llu", (unsigned long long)val);
207 208 break;
208 209 }
209 210
210 211 case DATA_TYPE_DOUBLE: {
211 212 double val;
212 213 VERIFY0(nvpair_value_double(curr, &val));
213 214 FPRINTF(fp, "%f", val);
214 215 break;
215 216 }
216 217
217 218 case DATA_TYPE_NVLIST: {
218 219 if (nvlist_print_json(fp,
219 220 fnvpair_value_nvlist(curr)) == -1)
220 221 return (-1);
221 222 break;
222 223 }
223 224
224 225 case DATA_TYPE_STRING_ARRAY: {
225 226 char **val;
226 227 uint_t valsz, i;
227 228 VERIFY0(nvpair_value_string_array(curr, &val, &valsz));
228 229 FPRINTF(fp, "[");
229 230 for (i = 0; i < valsz; i++) {
230 231 if (i > 0)
231 232 FPRINTF(fp, ",");
232 233 if (nvlist_print_json_string(fp, val[i]) == -1)
233 234 return (-1);
234 235 }
235 236 FPRINTF(fp, "]");
236 237 break;
237 238 }
238 239
239 240 case DATA_TYPE_NVLIST_ARRAY: {
240 241 nvlist_t **val;
241 242 uint_t valsz, i;
242 243 VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz));
243 244 FPRINTF(fp, "[");
244 245 for (i = 0; i < valsz; i++) {
245 246 if (i > 0)
246 247 FPRINTF(fp, ",");
247 248 if (nvlist_print_json(fp, val[i]) == -1)
248 249 return (-1);
249 250 }
250 251 FPRINTF(fp, "]");
251 252 break;
252 253 }
253 254
254 255 case DATA_TYPE_BOOLEAN_ARRAY: {
255 256 boolean_t *val;
256 257 uint_t valsz, i;
257 258 VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz));
258 259 FPRINTF(fp, "[");
259 260 for (i = 0; i < valsz; i++) {
260 261 if (i > 0)
261 262 FPRINTF(fp, ",");
262 263 FPRINTF(fp, val[i] == B_TRUE ?
263 264 "true" : "false");
264 265 }
265 266 FPRINTF(fp, "]");
266 267 break;
267 268 }
268 269
269 270 case DATA_TYPE_BYTE_ARRAY: {
270 271 uchar_t *val;
271 272 uint_t valsz, i;
272 273 VERIFY0(nvpair_value_byte_array(curr, &val, &valsz));
273 274 FPRINTF(fp, "[");
274 275 for (i = 0; i < valsz; i++) {
275 276 if (i > 0)
276 277 FPRINTF(fp, ",");
277 278 FPRINTF(fp, "%hhu", val[i]);
278 279 }
279 280 FPRINTF(fp, "]");
280 281 break;
281 282 }
282 283
283 284 case DATA_TYPE_UINT8_ARRAY: {
284 285 uint8_t *val;
285 286 uint_t valsz, i;
286 287 VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz));
287 288 FPRINTF(fp, "[");
288 289 for (i = 0; i < valsz; i++) {
289 290 if (i > 0)
290 291 FPRINTF(fp, ",");
291 292 FPRINTF(fp, "%hhu", val[i]);
292 293 }
293 294 FPRINTF(fp, "]");
294 295 break;
295 296 }
296 297
297 298 case DATA_TYPE_INT8_ARRAY: {
298 299 int8_t *val;
299 300 uint_t valsz, i;
300 301 VERIFY0(nvpair_value_int8_array(curr, &val, &valsz));
301 302 FPRINTF(fp, "[");
302 303 for (i = 0; i < valsz; i++) {
303 304 if (i > 0)
304 305 FPRINTF(fp, ",");
305 306 FPRINTF(fp, "%hd", val[i]);
306 307 }
307 308 FPRINTF(fp, "]");
308 309 break;
309 310 }
310 311
311 312 case DATA_TYPE_UINT16_ARRAY: {
312 313 uint16_t *val;
313 314 uint_t valsz, i;
314 315 VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz));
315 316 FPRINTF(fp, "[");
316 317 for (i = 0; i < valsz; i++) {
317 318 if (i > 0)
318 319 FPRINTF(fp, ",");
319 320 FPRINTF(fp, "%hu", val[i]);
320 321 }
321 322 FPRINTF(fp, "]");
322 323 break;
323 324 }
324 325
325 326 case DATA_TYPE_INT16_ARRAY: {
326 327 int16_t *val;
327 328 uint_t valsz, i;
328 329 VERIFY0(nvpair_value_int16_array(curr, &val, &valsz));
329 330 FPRINTF(fp, "[");
330 331 for (i = 0; i < valsz; i++) {
331 332 if (i > 0)
332 333 FPRINTF(fp, ",");
333 334 FPRINTF(fp, "%hd", val[i]);
334 335 }
335 336 FPRINTF(fp, "]");
336 337 break;
337 338 }
338 339
339 340 case DATA_TYPE_UINT32_ARRAY: {
340 341 uint32_t *val;
341 342 uint_t valsz, i;
342 343 VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz));
343 344 FPRINTF(fp, "[");
344 345 for (i = 0; i < valsz; i++) {
345 346 if (i > 0)
346 347 FPRINTF(fp, ",");
347 348 FPRINTF(fp, "%u", val[i]);
348 349 }
349 350 FPRINTF(fp, "]");
350 351 break;
351 352 }
352 353
353 354 case DATA_TYPE_INT32_ARRAY: {
354 355 int32_t *val;
355 356 uint_t valsz, i;
356 357 VERIFY0(nvpair_value_int32_array(curr, &val, &valsz));
357 358 FPRINTF(fp, "[");
358 359 for (i = 0; i < valsz; i++) {
359 360 if (i > 0)
360 361 FPRINTF(fp, ",");
361 362 FPRINTF(fp, "%d", val[i]);
362 363 }
363 364 FPRINTF(fp, "]");
364 365 break;
365 366 }
366 367
367 368 case DATA_TYPE_UINT64_ARRAY: {
368 369 uint64_t *val;
369 370 uint_t valsz, i;
370 371 VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz));
371 372 FPRINTF(fp, "[");
372 373 for (i = 0; i < valsz; i++) {
373 374 if (i > 0)
374 375 FPRINTF(fp, ",");
375 376 FPRINTF(fp, "%llu",
376 377 (unsigned long long)val[i]);
377 378 }
378 379 FPRINTF(fp, "]");
379 380 break;
380 381 }
381 382
382 383 case DATA_TYPE_INT64_ARRAY: {
383 384 int64_t *val;
384 385 uint_t valsz, i;
385 386 VERIFY0(nvpair_value_int64_array(curr, &val, &valsz));
386 387 FPRINTF(fp, "[");
387 388 for (i = 0; i < valsz; i++) {
388 389 if (i > 0)
389 390 FPRINTF(fp, ",");
390 391 FPRINTF(fp, "%lld", (long long)val[i]);
391 392 }
392 393 FPRINTF(fp, "]");
393 394 break;
394 395 }
395 396
396 397 case DATA_TYPE_UNKNOWN:
397 398 return (-1);
398 399 }
399 400 }
400 401
401 402 FPRINTF(fp, "}");
402 403 return (0);
403 404 }
|
↓ open down ↓ |
382 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX