mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	It now can have negative value to suppress the message entirely. So it needs to check it being positive. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: kernel-team@lge.com Link: http://lkml.kernel.org/r/20170217081742.17417-3-namhyung@kernel.org [ Adjust fuzz on tools/perf/util/pmu.c, add > 0 checks in many other places ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
		
			
				
	
	
		
			162 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Parse JSON files using the JSMN parser. */
 | 
						|
 | 
						|
/*
 | 
						|
 * Copyright (c) 2014, Intel Corporation
 | 
						|
 * All rights reserved.
 | 
						|
 *
 | 
						|
 * Redistribution and use in source and binary forms, with or without
 | 
						|
 * modification, are permitted provided that the following conditions are met:
 | 
						|
 *
 | 
						|
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
						|
 * this list of conditions and the following disclaimer.
 | 
						|
 *
 | 
						|
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
						|
 * notice, this list of conditions and the following disclaimer in the
 | 
						|
 * documentation and/or other materials provided with the distribution.
 | 
						|
 *
 | 
						|
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
						|
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
						|
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
						|
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
						|
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 | 
						|
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
						|
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | 
						|
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
						|
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
						|
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
						|
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 | 
						|
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
*/
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <sys/mman.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include "jsmn.h"
 | 
						|
#include "json.h"
 | 
						|
#include <linux/kernel.h>
 | 
						|
 | 
						|
 | 
						|
static char *mapfile(const char *fn, size_t *size)
 | 
						|
{
 | 
						|
	unsigned ps = sysconf(_SC_PAGESIZE);
 | 
						|
	struct stat st;
 | 
						|
	char *map = NULL;
 | 
						|
	int err;
 | 
						|
	int fd = open(fn, O_RDONLY);
 | 
						|
 | 
						|
	if (fd < 0 && verbose > 0 && fn) {
 | 
						|
		pr_err("Error opening events file '%s': %s\n", fn,
 | 
						|
				strerror(errno));
 | 
						|
	}
 | 
						|
 | 
						|
	if (fd < 0)
 | 
						|
		return NULL;
 | 
						|
	err = fstat(fd, &st);
 | 
						|
	if (err < 0)
 | 
						|
		goto out;
 | 
						|
	*size = st.st_size;
 | 
						|
	map = mmap(NULL,
 | 
						|
		   (st.st_size + ps - 1) & ~(ps - 1),
 | 
						|
		   PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
 | 
						|
	if (map == MAP_FAILED)
 | 
						|
		map = NULL;
 | 
						|
out:
 | 
						|
	close(fd);
 | 
						|
	return map;
 | 
						|
}
 | 
						|
 | 
						|
static void unmapfile(char *map, size_t size)
 | 
						|
{
 | 
						|
	unsigned ps = sysconf(_SC_PAGESIZE);
 | 
						|
	munmap(map, roundup(size, ps));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Parse json file using jsmn. Return array of tokens,
 | 
						|
 * and mapped file. Caller needs to free array.
 | 
						|
 */
 | 
						|
jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len)
 | 
						|
{
 | 
						|
	jsmn_parser parser;
 | 
						|
	jsmntok_t *tokens;
 | 
						|
	jsmnerr_t res;
 | 
						|
	unsigned sz;
 | 
						|
 | 
						|
	*map = mapfile(fn, size);
 | 
						|
	if (!*map)
 | 
						|
		return NULL;
 | 
						|
	/* Heuristic */
 | 
						|
	sz = *size * 16;
 | 
						|
	tokens = malloc(sz);
 | 
						|
	if (!tokens)
 | 
						|
		goto error;
 | 
						|
	jsmn_init(&parser);
 | 
						|
	res = jsmn_parse(&parser, *map, *size, tokens,
 | 
						|
			 sz / sizeof(jsmntok_t));
 | 
						|
	if (res != JSMN_SUCCESS) {
 | 
						|
		pr_err("%s: json error %s\n", fn, jsmn_strerror(res));
 | 
						|
		goto error_free;
 | 
						|
	}
 | 
						|
	if (len)
 | 
						|
		*len = parser.toknext;
 | 
						|
	return tokens;
 | 
						|
error_free:
 | 
						|
	free(tokens);
 | 
						|
error:
 | 
						|
	unmapfile(*map, *size);
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
void free_json(char *map, size_t size, jsmntok_t *tokens)
 | 
						|
{
 | 
						|
	free(tokens);
 | 
						|
	unmapfile(map, size);
 | 
						|
}
 | 
						|
 | 
						|
static int countchar(char *map, char c, int end)
 | 
						|
{
 | 
						|
	int i;
 | 
						|
	int count = 0;
 | 
						|
	for (i = 0; i < end; i++)
 | 
						|
		if (map[i] == c)
 | 
						|
			count++;
 | 
						|
	return count;
 | 
						|
}
 | 
						|
 | 
						|
/* Return line number of a jsmn token */
 | 
						|
int json_line(char *map, jsmntok_t *t)
 | 
						|
{
 | 
						|
	return countchar(map, '\n', t->start) + 1;
 | 
						|
}
 | 
						|
 | 
						|
static const char * const jsmn_types[] = {
 | 
						|
	[JSMN_PRIMITIVE] = "primitive",
 | 
						|
	[JSMN_ARRAY] = "array",
 | 
						|
	[JSMN_OBJECT] = "object",
 | 
						|
	[JSMN_STRING] = "string"
 | 
						|
};
 | 
						|
 | 
						|
#define LOOKUP(a, i) ((i) < (sizeof(a)/sizeof(*(a))) ? ((a)[i]) : "?")
 | 
						|
 | 
						|
/* Return type name of a jsmn token */
 | 
						|
const char *json_name(jsmntok_t *t)
 | 
						|
{
 | 
						|
	return LOOKUP(jsmn_types, t->type);
 | 
						|
}
 | 
						|
 | 
						|
int json_len(jsmntok_t *t)
 | 
						|
{
 | 
						|
	return t->end - t->start;
 | 
						|
}
 | 
						|
 | 
						|
/* Is string t equal to s? */
 | 
						|
int json_streq(char *map, jsmntok_t *t, const char *s)
 | 
						|
{
 | 
						|
	unsigned len = json_len(t);
 | 
						|
	return len == strlen(s) && !strncasecmp(map + t->start, s, len);
 | 
						|
}
 |