Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Same hash generated for two different functions with similar names #6708

Closed
JustinLloyd opened this issue Aug 11, 2021 · 3 comments · Fixed by #7017
Closed

Same hash generated for two different functions with similar names #6708

JustinLloyd opened this issue Aug 11, 2021 · 3 comments · Fixed by #7017

Comments

@JustinLloyd
Copy link

JustinLloyd commented Aug 11, 2021

🐛 bug report

During a production build Parcel or possibly Terser generates the same function hash for two different functions:

I have created a project using Parcel that includes jquery, gsap and pixi.js as dependencies. A development build works as expected, but a production build generates the same function hash for two different, but similarly named functions:
These two functions:

$parcel$export($a43a28938b26b986$exports, "hex2rgb", () => $a43a28938b26b986$export$9b426722ac942144);
$parcel$export($a43a28938b26b986$exports, "rgb2hex", () => $a43a28938b26b986$export$9b426722ac942144);

These two functions are part of pixi.js.

/**
 * Converts a hexadecimal color number to an [R, G, B] array of normalized floats (numbers from 0.0 to 1.0).
 *
 * @example
 * PIXI.utils.hex2rgb(0xffffff); // returns [1, 1, 1]
 * @memberof PIXI.utils
 * @function hex2rgb
 * @param {number} hex - The hexadecimal number to convert
 * @param  {number[]} [out=[]] - If supplied, this array will be used rather than returning a new one
 * @return {number[]} An array representing the [R, G, B] of the color where all values are floats.
 */ function $a43a28938b26b986$export$9b426722ac942144(hex, out) {
    if (out === void 0) out = [];
    out[0] = (hex >> 16 & 255) / 255;
    out[1] = (hex >> 8 & 255) / 255;
    out[2] = (hex & 255) / 255;
    return out;
}

/**
 * Converts a color as an [R, G, B] array of normalized floats to a hexadecimal number.
 *
 * @example
 * PIXI.utils.rgb2hex([1, 1, 1]); // returns 0xffffff
 * @memberof PIXI.utils
 * @function rgb2hex
 * @param {number[]} rgb - Array of numbers where all values are normalized floats from 0.0 to 1.0.
 * @return {number} Number in hexadecimal.
 */ function $a43a28938b26b986$export$9b426722ac942144(rgb) {
    return (rgb[0] * 255 << 16) + (rgb[1] * 255 << 8) + (rgb[2] * 255 | 0);
}

Which as you can see are clearly different, with different signatures, but it seems a hash collision occurs on the names: hex2rgb and rgb2hex.

🤔 Expected Behavior

Generate different hash based on different functions.

😯 Current Behavior

Generates the same hash based on different functions.

This is the error I get in the browser when loading the code:

11:15:58.100 Uncaught SyntaxError: redeclaration of function
$a43a28938b26b986$export$9b426722ac942144invaders.1fffc83b.js:10983:13
note: Previously declared at line 10932, column 13invaders.1fffc83b.js:10932:13

💁 Possible Solution

Conflict occurs during hash of function name. Suggestion would be to hash on the function and signature, or add some randomization to the hash.

🔦 Context

Cannot produce a working production build when including pixi.js as part of the bundle.

💻 Code Sample

🌍 Your Environment

Software Version(s)
Parcel 2.0.0-rc.0
terser 5.7.1
Node 13.9.0
npm/Yarn 6.13.7
Operating System Windows 10 Pro for Workstations

EDIT: Fixed typo.

@mischnic
Copy link
Member

mischnic commented Aug 11, 2021

Can be reproduced with

// index.js
import * as x from "./x.js";
console.log(x);

// x.js
export function hex2rgb() {
    return "hex2rgb";
}

export function rgb2hex() {
    return "rgb2hex";
}

At least in this simple example, it's not a collision of the Rust hashing function that's used for that (but I don't know why I'm not getting the hash that Parcel outputs in the bundle)

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

macro_rules! hash {
    ($str:expr) => {{
        let mut hasher = DefaultHasher::new();
        $str.hash(&mut hasher);
        hasher.finish()
    }};
}

fn main() {
    let str1 = "hex2rgb";
    let str2 = "rgb2hex";
    println!("{:x}", hash!(str1)); // dc42ded1fdd0428a
    println!("{:x}", hash!(str2)); // 8b15b4e588fd1a8
}

format!("${}$export${:x}", self.module_id, hash!(exported)).into()

@beepboopitschloe
Copy link

seeing this as well on v2.0.0-rc0 with the same input (pixi.js).

@devongovett devongovett added this to the v2.0.0 milestone Oct 4, 2021
@devongovett
Copy link
Member

I believe this is caused by servo/string-cache#224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants