@mocoto/mahoraga 0.14.6 → 0.14.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +170 -508
- package/dist/analysts/css/analysts/analyst-css.js +10 -1
- package/dist/analysts/detectors/detector-bugs-ml.js +81 -19
- package/dist/analysts/react/analysts/analyst-react-hooks.js +109 -90
- package/dist/analysts/react/detectors/detector-react-best-practices.js +100 -6
- package/dist/cli/commands/command-perf.js +1 -1
- package/dist/cli/commands/command-update.js +3 -2
- package/dist/core/messages/en/core/formatters-messages.js +1 -0
- package/dist/core/messages/ja/core/formatters-messages.js +1 -0
- package/dist/core/messages/pt/core/formatters-messages.js +1 -0
- package/dist/core/messages/zh/core/formatters-messages.js +1 -0
- package/dist/core/parsing/langs/typescript.js +27 -7
- package/dist/core/utils/exec-safe.js +47 -25
- package/package.json +10 -17
|
@@ -1,19 +1,32 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
import {
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import path from 'node:path';
|
|
3
4
|
import { config } from '../config/index.js';
|
|
4
5
|
import { getMessages } from '../messages/index.js';
|
|
5
|
-
// Expressão regular para detectar shell metacharacters perigosos
|
|
6
|
-
// que permitiriam injeção de comandos adicionais.
|
|
7
|
-
// Bloqueia: ; | & ` $() ${} <> \n
|
|
8
|
-
const SHELL_INJECTION_RE = /[;|&`]|\$[({]|\${|>|<|\\n/;
|
|
9
6
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* Allowlist de binários que o CLI pode executar externamente.
|
|
8
|
+
* Apenas comandos essenciais para operação do ferramenta são permitidos.
|
|
9
|
+
* Isso substitui a abordagem anterior de blacklist de caracteres shell,
|
|
10
|
+
* eliminando o vetor de injeção por shell intermediário.
|
|
13
11
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const BINARIOS_PERMITIDOS = new Set([
|
|
13
|
+
'git',
|
|
14
|
+
'npm',
|
|
15
|
+
'npx',
|
|
16
|
+
'node',
|
|
17
|
+
'pnpm',
|
|
18
|
+
'yarn',
|
|
19
|
+
'corepack',
|
|
20
|
+
]);
|
|
21
|
+
/**
|
|
22
|
+
* Valida que o binário está na allowlist.
|
|
23
|
+
* @param bin - Caminho ou nome do binário
|
|
24
|
+
* @throws Error se o binário não for permitido
|
|
25
|
+
*/
|
|
26
|
+
function validarBinario(bin) {
|
|
27
|
+
const nome = path.basename(bin);
|
|
28
|
+
if (!BINARIOS_PERMITIDOS.has(nome)) {
|
|
29
|
+
throw new Error(getMessages().ExecSafeMensagens.binarioNaoPermitido(bin));
|
|
17
30
|
}
|
|
18
31
|
}
|
|
19
32
|
function verificarSafeMode() {
|
|
@@ -22,28 +35,37 @@ function verificarSafeMode() {
|
|
|
22
35
|
}
|
|
23
36
|
}
|
|
24
37
|
/**
|
|
25
|
-
* Executa um
|
|
38
|
+
* Executa um binário de forma segura sem shell intermediário.
|
|
39
|
+
*
|
|
26
40
|
* Bloqueia a execução quando SAFE_MODE está ativo e ALLOW_EXEC não está habilitado.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
41
|
+
* Valida o binário contra uma allowlist de comandos permitidos.
|
|
42
|
+
* Força `shell: false` para eliminar o risco de injeção de comandos.
|
|
43
|
+
*
|
|
44
|
+
* @param bin - Binário a executar (ex: 'git', 'npm')
|
|
45
|
+
* @param args - Argumentos do binário (array de strings)
|
|
46
|
+
* @param opts - Opções adicionais do child_process
|
|
30
47
|
* @returns Buffer ou string com a saída do comando
|
|
31
|
-
* @throws Error se SAFE_MODE estiver ativo sem ALLOW_EXEC
|
|
48
|
+
* @throws Error se SAFE_MODE estiver ativo sem ALLOW_EXEC,
|
|
49
|
+
* se o binário não estiver na allowlist,
|
|
50
|
+
* ou se a execução falhar
|
|
32
51
|
*/
|
|
33
|
-
export function executarShellSeguro(
|
|
34
|
-
|
|
52
|
+
export function executarShellSeguro(bin, args = [], opts = {}) {
|
|
53
|
+
validarBinario(bin);
|
|
35
54
|
verificarSafeMode();
|
|
36
|
-
return
|
|
55
|
+
return execFileSync(bin, args, { ...opts, shell: false });
|
|
37
56
|
}
|
|
38
57
|
/**
|
|
39
58
|
* Versão assíncrona do `executarShellSeguro`.
|
|
40
59
|
* Wrapper async que delega ao sync, útil em contextos que já utilizam await.
|
|
41
|
-
*
|
|
42
|
-
* @param
|
|
60
|
+
*
|
|
61
|
+
* @param bin - Binário a executar (ex: 'git', 'npm')
|
|
62
|
+
* @param args - Argumentos do binário (array de strings)
|
|
63
|
+
* @param opts - Opções adicionais do child_process
|
|
43
64
|
* @returns Promise resolvida com Buffer ou string da saída do comando
|
|
44
|
-
* @throws Error se SAFE_MODE estiver ativo sem ALLOW_EXEC
|
|
65
|
+
* @throws Error se SAFE_MODE estiver ativo sem ALLOW_EXEC,
|
|
66
|
+
* se o binário não estiver na allowlist,
|
|
67
|
+
* ou se a execução falhar
|
|
45
68
|
*/
|
|
46
|
-
export function executarShellSeguroAsync(
|
|
47
|
-
|
|
48
|
-
return executarShellSeguro(cmd, opts);
|
|
69
|
+
export function executarShellSeguroAsync(bin, args = [], opts = {}) {
|
|
70
|
+
return executarShellSeguro(bin, args, opts);
|
|
49
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mocoto/mahoraga",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "C.L.I modular para análise, diagnóstico e manutenção de projetos JavaScript/TypeScript e multi-stack leve",
|
|
6
6
|
"author": "rei macaco",
|
|
@@ -116,46 +116,39 @@
|
|
|
116
116
|
"THIRD-PARTY-NOTICES.txt"
|
|
117
117
|
],
|
|
118
118
|
"dependencies": {
|
|
119
|
-
"@babel/parser": "^8.0.
|
|
120
|
-
"@babel/traverse": "^8.0.
|
|
121
|
-
"@babel/types": "^8.0.
|
|
119
|
+
"@babel/parser": "^8.0.4",
|
|
120
|
+
"@babel/traverse": "^8.0.4",
|
|
121
|
+
"@babel/types": "^8.0.4",
|
|
122
122
|
"chalk": "^5.6.2",
|
|
123
123
|
"commander": "^15.0.0",
|
|
124
124
|
"dotenv": "^17.4.2",
|
|
125
125
|
"fast-xml-parser": "^5.9.3",
|
|
126
126
|
"htmlparser2": "^12.0.0",
|
|
127
|
-
"marked": "^18.0.
|
|
127
|
+
"marked": "^18.0.6",
|
|
128
128
|
"micromatch": "^4.0.8",
|
|
129
129
|
"minimatch": "^10.2.5",
|
|
130
130
|
"openpgp": "^6.3.1",
|
|
131
131
|
"ora": "^9.4.1",
|
|
132
132
|
"p-limit": "^7.3.0",
|
|
133
|
+
"postcss": "^8.5.16",
|
|
133
134
|
"postcss-sass": "^0.5.0",
|
|
134
135
|
"postcss-scss": "^4.0.9",
|
|
135
136
|
"xxhashjs": "^0.2.2",
|
|
136
|
-
"yaml": "^2.9.0"
|
|
137
|
-
"postcss": "^8.5.16"
|
|
137
|
+
"yaml": "^2.9.0"
|
|
138
138
|
},
|
|
139
139
|
"devDependencies": {
|
|
140
140
|
"@types/micromatch": "^4.0.10",
|
|
141
|
-
"@types/node": "^26.1.
|
|
142
|
-
"@typescript-eslint/eslint-plugin": "^8.62.1",
|
|
143
|
-
"@typescript-eslint/parser": "^8.62.1",
|
|
141
|
+
"@types/node": "^26.1.1",
|
|
144
142
|
"@vitest/coverage-istanbul": "^4.1.8",
|
|
145
143
|
"@vitest/coverage-v8": "^4.1.8",
|
|
146
144
|
"autoprefixer": "^10.5.2",
|
|
147
|
-
"eslint": "^10.6.0",
|
|
148
|
-
"eslint-import-resolver-typescript": "^4.4.5",
|
|
149
|
-
"eslint-plugin-import-x": "^4.17.1",
|
|
150
|
-
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
151
|
-
"eslint-plugin-unused-imports": "^4.4.1",
|
|
152
145
|
"husky": "^9.1.7",
|
|
153
146
|
"license-checker-rseidelsohn": "^5.0.1",
|
|
154
147
|
"lint-staged": "^17.0.8",
|
|
155
148
|
"rimraf": "^6.1.3",
|
|
156
|
-
"tsc-alias": "^1.
|
|
149
|
+
"tsc-alias": "^1.9.0",
|
|
157
150
|
"tsx": "^4.23.0",
|
|
158
|
-
"typescript": "^
|
|
151
|
+
"typescript": "^7.0.2",
|
|
159
152
|
"vitest": "^4.1.8"
|
|
160
153
|
},
|
|
161
154
|
"lint-staged": {
|