[Git][java-team/openrefine-butterfly][upstream] New upstream version 1.2.6

Markus Koschany (@apo) gitlab at salsa.debian.org
Thu Jan 2 18:44:04 GMT 2025



Markus Koschany pushed to branch upstream at Debian Java Maintainers / openrefine-butterfly


Commits:
320296ea by Markus Koschany at 2025-01-02T19:31:42+01:00
New upstream version 1.2.6
- - - - -


6 changed files:

- .github/workflows/maven.yml
- main/pom.xml
- main/src/edu/mit/simile/butterfly/Butterfly.js
- main/src/edu/mit/simile/butterfly/ButterflyModuleImpl.java
- + main/tests/src/edu/mit/simile/butterfly/tests/ButterflyModuleImplTests.java
- pom.xml


Changes:

=====================================
.github/workflows/maven.yml
=====================================
@@ -13,7 +13,7 @@ jobs:
   build:
     strategy:
       matrix:
-        java: [ 11, 16 ]
+        java: [ 11, 21 ]
 
     runs-on: ubuntu-latest
 


=====================================
main/pom.xml
=====================================
@@ -7,12 +7,12 @@
   <parent>
     <groupId>org.openrefine.dependencies</groupId>
     <artifactId>butterfly-container</artifactId>
-    <version>1.2.5</version>
+    <version>1.2.6</version>
   </parent>
   
   <groupId>org.openrefine.dependencies</groupId>
   <artifactId>butterfly</artifactId>
-  <version>1.2.5</version>
+  <version>1.2.6</version>
 
   <name>SIMILE Butterfly Engine</name>
   <url>https://github.com/OpenRefine/simile-butterfly/</url>
@@ -51,7 +51,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
-        <version>3.0.0</version>
+        <version>3.2.5</version>
         <configuration>
           <suiteXmlFiles>
             <suiteXmlFile>tests/conf/tests.xml</suiteXmlFile>
@@ -70,7 +70,7 @@
     <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
-      <version>2.11.0</version>
+      <version>2.16.1</version>
     </dependency>
     <dependency>
       <groupId>commons-lang</groupId>
@@ -85,7 +85,7 @@
     <dependency>
       <groupId>org.mozilla</groupId>
       <artifactId>rhino</artifactId>
-      <version>1.7.14</version>
+      <version>1.7.15</version>
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
@@ -100,7 +100,7 @@
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
-      <version>2.0.6</version>
+      <version>2.0.13</version>
     </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
@@ -111,13 +111,13 @@
     <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
-      <version>7.6.1</version>
+      <version>7.10.2</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
-      <version>5.2.0</version>
+      <version>5.12.0</version>
       <scope>test</scope>
     </dependency>
   </dependencies>


=====================================
main/src/edu/mit/simile/butterfly/Butterfly.js
=====================================
@@ -5,32 +5,6 @@
  * to define 'glue' and 'syntax sugar' functions.
  */
  
-/*
- * Perform the JSON serialization in javascript and send the serialized string over
- */
-Butterfly.prototype.sendJSON = function(request, response, object, wrap) {
-	var json = butterfly.toJSONString(object);
-	if (wrap) json = "<textarea>" + json + "</textarea>";
-	this.sendString(request, response, json, "UTF-8", "text/plain");
-}
-
-/*
- * Perform the JSON serialization in javascript and send the serialized string over 
- * wrapped in a callback function call
- */
-Butterfly.prototype.sendJSONP = function(request, response, object, callback) {
-	var json = butterfly.toJSONString(object);
-	this.sendString(request, response, callback + "(" + json + ");", "UTF-8", "text/plain");
-}
-
-/*
- * Obtain the request payload as a JSON object using the given optional filtering 
- * function to perform more specific data-type conversion
- */
-Butterfly.prototype.getJSON = function(request) {
-    return butterfly.parseJSON(this.getString(request));
-}
-
 /*
  * Return the module path wirings as a JSON object.
  */
@@ -46,131 +20,7 @@ Butterfly.prototype.getWirings = function(request) {
     return result;
 }
 
-// ---------------------------------------------------------------------------------------
-
-Butterfly.prototype.toJSONString = function(o) {
-    if (o instanceof Object) {
-        var str = s.object(o);
-    } else if (o instanceof Array) {
-        var str = s.array(o);
-    } else {
-        var str = o.toString();
-    }
-    return str;
-};
-
-var JSON_cleaning_RE = /"(\\.|[^"\\])*"/g;
-var JSON_problematic_RE = /[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/;
-
-Butterfly.prototype.parseJSON = function (str) {
-    try {
-    	var s = new String(str); // NOTE(SM) this is to avoid nasty ambiguous java/javascript 
-    	                         // mappings on the 'replace' call below
-    	var cleaned_str = s.replace(JSON_cleaning_RE, "");
-        if (!(JSON_problematic_RE.test(cleaned_str))) {
-            return eval('(' + str + ')');
-        }
-    } catch (e) {
-        butterfly.log(e);
-    }
-};
 
-/*
- *  Adapted from http://www.json.org/json.js.
- */
-    
-var m = {
-    '\b': '\\b',
-    '\t': '\\t',
-    '\n': '\\n',
-    '\f': '\\f',
-    '\r': '\\r',
-    '"' : '\\"',
-    '\\': '\\\\'
-};
-
-var s = {
-
-    object: function (x) {
-        if (x) {
-            var h = x.hashCode;
-            if (h && (typeof h == "function")) { // here we identify Java objects that are wrapped and made available to javascript
-                var str = "" + x.toString(); // IMPORTANT: this converts a Java String object into a JavaScript string object!
-                return s.string(str); 
-            } else if (x instanceof Array || ("0" in x && "length" in x)) { // HACK: this tries to detect arrays
-            	return s.array(x);
-            } else {
-                var a = ['{'], b, f, i, v;
-                for (i in x) {
-                    if (typeof i === 'string' && Object.prototype.hasOwnProperty.apply(x, [i])) {                    
-                        v = x[i];
-                        f = s[typeof v];
-                        if (f) {
-                            v = f(v);
-                            if (typeof v == 'string') {
-                                if (b) {
-                                    a[a.length] = ',';
-                                }
-                                a.push(s.string(i), ':', v);
-                                b = true;
-                            }
-                        }
-                    }
-                }
-                a[a.length] = '}';
-                return a.join('');
-            }
-        }
-        return 'null';
-    },
-
-    array: function (x) {
-        var a = ['['], b, f, i, l = x.length, v;
-        for (i = 0; i < l; i += 1) {
-            v = x[i];
-            f = s[typeof v];
-            if (f) {
-                v = f(v);
-                if (typeof v == 'string') {
-                    if (b) {
-                        a[a.length] = ',';
-                    }
-                    a[a.length] = v;
-                    b = true;
-                }
-            }
-        }
-        a[a.length] = ']';
-        return a.join('');
-    },
-
-    'null': function (x) {
-        return "null";
-    },
-
-    'boolean': function (x) {
-        return String(x);
-    },
-
-    number: function (x) {
-        return isFinite(x) ? String(x) : 'null';
-    },
-
-    string: function (x) {
-        if (/["\\\x00-\x1f]/.test(x)) {
-            x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
-                var c = m[b];
-                if (c) {
-                    return c;
-                }
-                c = b.charCodeAt();
-                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
-            });
-        }
-        return '"' + x + '"';
-    }
-};
- 
 // ---------------------------------------------------------------------------------------
 
 String.prototype.trim = function() {


=====================================
main/src/edu/mit/simile/butterfly/ButterflyModuleImpl.java
=====================================
@@ -14,6 +14,7 @@ import java.io.Writer;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -71,6 +72,7 @@ public class ButterflyModuleImpl implements ButterflyModule {
     protected Timer _timer;
     protected ServletConfig _config;
     protected File _path;
+    protected Path _normalizedPath;
     protected MountPoint _mountPoint;
     protected ButterflyMounter _mounter;
     protected String _name;
@@ -118,6 +120,7 @@ public class ButterflyModuleImpl implements ButterflyModule {
     public void setPath(File path) {
         _logger.trace("{} -(path)-> {}", this, path);
         this._path = path;
+        this._normalizedPath = path.toPath().toAbsolutePath().normalize();
     }
 
     public void setName(String name) {
@@ -259,6 +262,8 @@ public class ButterflyModuleImpl implements ButterflyModule {
 
     protected Pattern super_pattern = Pattern.compile("^@@(.*)@@$");
     
+    // TODO 2025-10: migrate away from URL as a return type to File/Path as we don't want this to fetch anything remote
+    @Override
     public URL getResource(String resource) {
         _logger.trace("> getResource({}->{},{})", new Object[] { _name, _extended, resource });
         URL u = null;
@@ -283,14 +288,11 @@ public class ButterflyModuleImpl implements ButterflyModule {
         
         if (u == null) {
             try {
-                if (resource.startsWith("file:/")) {
-                    u = new URL(resource);
-                } else {
-                    if (resource.charAt(0) == '/') resource = resource.substring(1);
-                    File f = new File(_path, resource);
-                    if (f.exists()) {
-                        u = f.toURI().toURL();
-                    }
+                if (resource.charAt(0) == '/') resource = resource.substring(1);
+                File f = new File(_path, resource);
+                // check that the file does not escape the expected directory
+                if (f.toPath().toAbsolutePath().normalize().startsWith(_normalizedPath) && f.exists()) {
+                    u = f.toURI().toURL();
                 }
             } catch (MalformedURLException e) {
                 _logger.error("Error", e);


=====================================
main/tests/src/edu/mit/simile/butterfly/tests/ButterflyModuleImplTests.java
=====================================
@@ -0,0 +1,53 @@
+package edu.mit.simile.butterfly.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.nio.file.Files;
+
+import edu.mit.simile.butterfly.ButterflyModuleImpl;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ButterflyModuleImplTests {
+    
+    ButterflyModuleImpl SUT;
+    File tempDir;
+    File firstFolder;
+    File secondFolder;
+    File textFile;
+    File testFile;
+    
+    @BeforeMethod
+    public void setUp() throws IOException {
+        SUT = new ButterflyModuleImpl();
+        tempDir = Files.createTempDirectory("ButterflyModuleImplTests").toFile();
+        tempDir.deleteOnExit();
+        firstFolder = new File(tempDir, "first_folder");
+        firstFolder.mkdir();
+        secondFolder = new File(tempDir, "other_folder");
+        secondFolder.mkdir();
+        textFile = new File(secondFolder, "file.txt");
+        textFile.createNewFile();
+        testFile = new File(firstFolder, "test.txt");
+        testFile.createNewFile();
+        SUT.setPath(firstFolder);
+    }
+    
+    @Test
+    public void testGetResource() throws MalformedURLException {
+        // file exists and is in the expected directory
+        Assert.assertEquals(SUT.getResource("test.txt"), testFile.toURI().toURL());
+        // file does not exist
+        Assert.assertNull(SUT.getResource("does_not_exist.xls"));
+        
+        // file exists but escapes the expected directory (it would be a security issue to accept it)
+        Assert.assertEquals(SUT.getResource("../other_folder/file.txt"), null);
+        // we don't support passing full URIs (it would be a security issue to accept reading any resource)
+        String fullURI = testFile.toURI().toString();
+        Assert.assertTrue(fullURI.startsWith("file:/"));
+        Assert.assertEquals(SUT.getResource(fullURI), null);
+    }
+
+}


=====================================
pom.xml
=====================================
@@ -12,7 +12,7 @@
 
   <groupId>org.openrefine.dependencies</groupId>
   <artifactId>butterfly-container</artifactId>
-  <version>1.2.5</version>
+  <version>1.2.6</version>
   <packaging>pom</packaging>
 
   <name>SIMILE Butterfly</name>
@@ -59,7 +59,7 @@
   </modules>
 
   <properties>
-    <log4j.version>2.18.0</log4j.version>
+    <log4j.version>2.23.1</log4j.version>
   </properties>
 
   <scm>
@@ -78,7 +78,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.11.0</version>
+        <version>3.13.0</version>
         <configuration>
           <source>1.8</source>
           <target>1.8</target>
@@ -88,7 +88,7 @@
         <inherited>true</inherited>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-source-plugin</artifactId>
-        <version>3.2.1</version>
+        <version>3.3.1</version>
         <executions>
           <execution>
             <id>attach-sources</id>
@@ -109,7 +109,7 @@
      <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-javadoc-plugin</artifactId>
-      <version>3.4.1</version>
+      <version>3.7.0</version>
       <configuration>
         <javadocExecutable>/usr/bin/javadoc</javadocExecutable>
         <source>8</source>
@@ -126,7 +126,7 @@
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-gpg-plugin</artifactId>
-      <version>3.0.1</version>
+      <version>3.2.4</version>
       <executions>
         <execution>
           <id>sign-artifacts</id>
@@ -146,7 +146,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-javadoc-plugin</artifactId>
-        <version>3.4.1</version>
+        <version>3.7.0</version>
         <configuration>
           <aggregate>true</aggregate>
           <source>1.8</source>
@@ -178,7 +178,7 @@
     <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
-      <version>7.6.1</version>
+      <version>7.10.2</version>
       <scope>test</scope>
     </dependency>
   </dependencies>



View it on GitLab: https://salsa.debian.org/java-team/openrefine-butterfly/-/commit/320296ea25f9be48634bf9c2c9c93e99b6966dea

-- 
View it on GitLab: https://salsa.debian.org/java-team/openrefine-butterfly/-/commit/320296ea25f9be48634bf9c2c9c93e99b6966dea
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20250102/a0e5dafc/attachment.htm>


More information about the pkg-java-commits mailing list