• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 23665300624

27 Mar 2026 08:06PM UTC coverage: 65.425% (+0.05%) from 65.373%
23665300624

push

github

ibacher
Follow-up for Java 8 support in ModuleResourcesServlet

0 of 2 new or added lines in 1 file covered. (0.0%)

164 existing lines in 5 files now uncovered.

23858 of 36466 relevant lines covered (65.43%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/web/src/main/java/org/openmrs/module/web/ModuleResourcesServlet.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.module.web;
11

12
import java.io.File;
13
import java.io.FileInputStream;
14
import java.io.IOException;
15
import java.nio.file.Path;
16
import java.nio.file.Paths;
17

18
import javax.servlet.ServletException;
19
import javax.servlet.http.HttpServlet;
20
import javax.servlet.http.HttpServletRequest;
21
import javax.servlet.http.HttpServletResponse;
22

23
import org.openmrs.module.Module;
24
import org.openmrs.module.ModuleUtil;
25
import org.openmrs.util.OpenmrsUtil;
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
28

UNCOV
29
public class ModuleResourcesServlet extends HttpServlet {
×
30
        
31
        private static final String MODULE_PATH = "/WEB-INF/view/module/";
32
        
33
        private static final long serialVersionUID = 1239820102030344L;
34
        
UNCOV
35
        private static final Logger log = LoggerFactory.getLogger(ModuleResourcesServlet.class);
×
36
        
37
        /**
38
         * Used for caching purposes
39
         *
40
         * @see javax.servlet.http.HttpServlet#getLastModified(javax.servlet.http.HttpServletRequest)
41
         */
42
        @Override
43
        protected long getLastModified(HttpServletRequest req) {
UNCOV
44
                File f = getFile(req);
×
45
                
46
                if (f == null) {
×
UNCOV
47
                        return super.getLastModified(req);
×
48
                }
49
                
UNCOV
50
                return f.lastModified();
×
51
        }
52
        
53
        @Override
54
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
55
                
UNCOV
56
                log.debug("In service method for module servlet: " + request.getPathInfo());
×
57
                
58
                File f = getFile(request);
×
59
                if (f == null) {
×
60
                        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
×
UNCOV
61
                        return;
×
62
                }
63
                
64
                response.setDateHeader("Last-Modified", f.lastModified());
×
65
                response.setContentLength(Long.valueOf(f.length()).intValue());
×
66
                String mimeType = getServletContext().getMimeType(f.getName());
×
UNCOV
67
                response.setContentType(mimeType);
×
68
                
UNCOV
69
                FileInputStream is = new FileInputStream(f);
×
70
                try {
UNCOV
71
                        OpenmrsUtil.copyFile(is, response.getOutputStream());
×
72
                }
73
                finally {
UNCOV
74
                        OpenmrsUtil.closeStream(is);
×
75
                }
UNCOV
76
        }
×
77
        
78
        /**
79
         * Turns the given request/path into a File object
80
         *
81
         * @param request the current http request
82
         * @return the file being requested or null if not found
83
         */
84
        protected File getFile(HttpServletRequest request) {
85
                
UNCOV
86
                String path = request.getPathInfo();
×
87
                
88
                Module module = ModuleUtil.getModuleForPath(path);
×
89
                if (module == null) {
×
90
                        log.warn("No module handles the path: " + path);
×
UNCOV
91
                        return null;
×
92
                }
93
                
94
                String relativePath = ModuleUtil.getPathForResource(module, path);
×
UNCOV
95
                String realPath = getServletContext().getRealPath("") + MODULE_PATH + module.getModuleIdAsPath() + "/resources"
×
96
                        + relativePath;
97

98
                String basePath;
99

100
                //if in dev mode, load resources from the development directory
UNCOV
101
                File devDir = ModuleUtil.getDevelopmentDirectory(module.getModuleId());
×
UNCOV
102
                if (devDir != null) {
×
103
                        realPath = devDir.getAbsolutePath() + "/omod/target/classes/web/module/resources" + relativePath;
×
UNCOV
104
                        basePath = devDir.getAbsolutePath() + "/omod/target/classes/web/module/resources";
×
105
                } else {
106
                        basePath = getServletContext().getRealPath("") + MODULE_PATH + module.getModuleIdAsPath() + "/resources";
×
107
                }
108

NEW
109
                Path normalizedPath = Paths.get(realPath).normalize();
×
NEW
110
                Path normalizedBase = Paths.get(basePath).normalize();
×
UNCOV
111
                if (!normalizedPath.startsWith(normalizedBase)) {
×
UNCOV
112
                        log.warn("Detected attempted directory traversal with path: " + path);
×
UNCOV
113
                        return null;
×
114
                }
115

UNCOV
116
                File f = normalizedPath.toFile();
×
UNCOV
117
                if (!f.exists()) {
×
UNCOV
118
                        log.warn("No file with path '" + normalizedPath + "' exists for module '" + module.getModuleId() + "'");
×
UNCOV
119
                        return null;
×
120
                }
121
                
UNCOV
122
                return f;
×
123
        }
124
        
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc