/*
- * Copyright (C) 2015 - EfficiOS Inc., Alexandre Montplaisir <alexmonthy@efficios.com>
+ * SPDX-License-Identifier: LGPL-2.1-only
*
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License, version 2.1 only,
- * as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (C) 2015 EfficiOS Inc.
+ * Copyright (C) 2015 Alexandre Montplaisir <alexmonthy@efficios.com>
*/
package org.lttng.ust.agent.context;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* The singleton manager of {@link IContextInfoRetriever} objects.
private static final String SHARED_LIBRARY_NAME = "lttng-ust-context-jni";
+ private static final Pattern VALID_CONTEXT_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_\\.]+$");
+
private static ContextInfoManager instance;
private final Map<String, IContextInfoRetriever> contextInfoRetrievers = new ConcurrentHashMap<String, IContextInfoRetriever>();
private final Map<String, Long> contextInforRetrieverRefs = new HashMap<String, Long>();
+ /**
+ * Lock used to keep the two maps above in sync when retrievers are
+ * registered or unregistered.
+ */
private final Object retrieverLock = new Object();
/** Singleton class, constructor should not be accessed directly */
*/
public boolean registerContextInfoRetriever(String retrieverName, IContextInfoRetriever contextInfoRetriever) {
synchronized (retrieverLock) {
+ if (!validateRetrieverName(retrieverName)) {
+ return false;
+ }
+
if (contextInfoRetrievers.containsKey(retrieverName)) {
/*
* There is already a retriever registered with that name,
* was none
*/
public IContextInfoRetriever getContextInfoRetriever(String retrieverName) {
+ /*
+ * Note that this method does not take the retrieverLock, it lets
+ * concurrent threads access the ConcurrentHashMap directly.
+ *
+ * It's fine for a get() to happen during a registration or
+ * unregistration, it's first-come-first-serve.
+ */
return contextInfoRetrievers.get(retrieverName);
}
+
+ /**
+ * Validate that the given retriever name contains only the allowed
+ * characters, which are alphanumerical characters, period "." and
+ * underscore "_". The name must also not start with a number.
+ */
+ private static boolean validateRetrieverName(String contextName) {
+ if (contextName.isEmpty()) {
+ return false;
+ }
+
+ /* First character must not be a number */
+ if (Character.isDigit(contextName.charAt(0))) {
+ return false;
+ }
+
+ /* Validate the other characters of the string */
+ Matcher matcher = VALID_CONTEXT_NAME_PATTERN.matcher(contextName);
+ return matcher.matches();
+ }
}