Skip to content

Commit 499bc04

Browse files
committed
[core][rewriter] destructure_rewrites: handle unshadowed location rewrites in var variable declaration
1 parent 04689da commit 499bc04

File tree

3 files changed

+50
-59
lines changed

3 files changed

+50
-59
lines changed

rewriter/js/src/changes.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub enum JsChangeType<'alloc: 'data, 'data> {
9595
CleanFunction {
9696
restids: Vec<Atom<'data>>,
9797
expression: bool,
98+
location_assigned: bool,
9899
},
99100
}
100101

@@ -162,19 +163,32 @@ impl<'alloc: 'data, 'data> Transform<'data> for JsChange<'alloc, 'data> {
162163
Ty::CleanFunction {
163164
restids,
164165
expression,
166+
location_assigned,
165167
} => {
166168
let mut steps = String::new();
167169

168170
if expression {
169171
for id in restids {
170172
steps.push_str(&format!("{}({}),", &cfg.cleanrestfn, id.as_str()));
171173
}
174+
if location_assigned {
175+
steps.push_str(&format!(
176+
"{}(location,\"=\",{})||(location={}),",
177+
&cfg.trysetfn, &cfg.templocid, &cfg.templocid
178+
));
179+
}
172180
let steps: &'static str = Box::leak(steps.into_boxed_str());
173181
LL::insert(transforms!["(", &steps])
174182
} else {
175183
for id in restids {
176184
steps.push_str(&format!("{}({});", &cfg.cleanrestfn, id.as_str()));
177185
}
186+
if location_assigned {
187+
steps.push_str(&format!(
188+
"{}(location,\"=\",{})||(location={});",
189+
&cfg.trysetfn, &cfg.templocid, &cfg.templocid
190+
));
191+
}
178192
let steps: &'static str = Box::leak(steps.into_boxed_str());
179193
LL::insert(transforms![";", &steps])
180194
}

rewriter/js/src/rewrite.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub(crate) enum RewriteType<'alloc: 'data, 'data> {
7676
CleanFunction {
7777
restids: Vec<Atom<'data>>,
7878
expression: bool,
79+
location_assigned: bool,
7980
},
8081

8182
// don't use for anything static, only use for stuff like rewriteurl
@@ -155,14 +156,16 @@ impl<'alloc: 'data, 'data> RewriteType<'alloc, 'data> {
155156
Self::CleanFunction {
156157
restids,
157158
expression,
159+
location_assigned,
158160
} => {
159161
if expression {
160162
smallvec![
161163
change!(
162164
Span::new(span.start, span.start),
163165
CleanFunction {
164166
restids,
165-
expression
167+
expression,
168+
location_assigned
166169
}
167170
),
168171
change!(
@@ -178,7 +181,8 @@ impl<'alloc: 'data, 'data> RewriteType<'alloc, 'data> {
178181
Span::new(span.start, span.start),
179182
CleanFunction {
180183
restids,
181-
expression
184+
expression,
185+
location_assigned
182186
}
183187
),]
184188
}

rewriter/js/src/visitor.rs

Lines changed: 30 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use oxc::{
1111
MemberExpression, MetaProperty, NewExpression, ObjectAssignmentTarget, ObjectExpression,
1212
ObjectPattern, ObjectPropertyKind, PrivateIdentifier, PropertyKey, ReturnStatement,
1313
SimpleAssignmentTarget, StringLiteral, ThisExpression, UnaryExpression, UnaryOperator,
14-
UpdateExpression,
14+
UpdateExpression, VariableDeclarationKind,
1515
},
16-
ast_visit::{Visit, walk},
16+
ast_visit::{walk, Visit},
1717
span::{Atom, GetSpan, Span},
1818
};
1919

@@ -245,6 +245,7 @@ where
245245
&mut self,
246246
it: &BindingPattern<'data>,
247247
restids: &mut Vec<Atom<'data>>,
248+
rewrite_location: bool,
248249
location_assigned: &mut bool,
249250
) {
250251
match &it.kind {
@@ -285,20 +286,20 @@ where
285286
self.jschanges.add(rewrite!(prop.key.span(), WrapProperty));
286287
}
287288
}
288-
self.recurse_binding_pattern(&prop.value, restids, location_assigned);
289+
self.recurse_binding_pattern(&prop.value, restids, rewrite_location, location_assigned);
289290
}
290291

291292
if let Some(r) = &p.rest {
292293
match &r.argument.kind {
293294
BindingPatternKind::BindingIdentifier(i) => {
294-
// if i.name == "location" {
295-
// self.jschanges.add(rewrite!(i.span, TempVar));
296-
// restids
297-
// .push(self.alloc.alloc_str(&self.config.templocid).into());
298-
// *location_assigned = true;
299-
// } else {
300-
restids.push(i.name);
301-
// }
295+
if rewrite_location && i.name == "location" {
296+
self.jschanges.add(rewrite!(i.span, TempVar));
297+
restids
298+
.push(self.alloc.alloc_str(&self.config.templocid).into());
299+
*location_assigned = true;
300+
} else {
301+
restids.push(i.name);
302+
}
302303
}
303304
_ => panic!("what?"),
304305
}
@@ -318,21 +319,10 @@ where
318319
E: UrlRewriter,
319320
{
320321
fn visit_identifier_reference(&mut self, it: &IdentifierReference) {
321-
// if self.config.capture_errors {
322-
// self.jschanges.insert(JsChange::GenericChange {
323-
// span: it.span,
324-
// text: format!(
325-
// "{}({}, typeof arguments != 'undefined' && arguments)",
326-
// self.config.wrapfn, it.name
327-
// ),
328-
// });
329-
// } else {
330-
//
331322
if UNSAFE_GLOBALS.contains(&it.name.as_str()) {
332323
self.jschanges
333324
.add(rewrite!(it.span, WrapFn { enclose: false }));
334325
}
335-
// }
336326
}
337327

338328
fn visit_new_expression(&mut self, it: &NewExpression<'data>) {
@@ -367,19 +357,7 @@ where
367357
MemberExpression::ComputedMemberExpression(s) => {
368358
self.walk_computed_member_expression(s);
369359
}
370-
_ => {} // if !self.flags.strict_rewrites
371-
// && !UNSAFE_GLOBALS.contains(&s.property.name.as_str())
372-
// && let Expression::Identifier(_) | Expression::ThisExpression(_) = &s.object
373-
// {
374-
// // cull tree - this should be safe
375-
// return;
376-
// }
377-
378-
// if self.flags.scramitize
379-
// && !matches!(s.object, Expression::MetaProperty(_) | Expression::Super(_))
380-
// {
381-
// self.scramitize(s.object.span());
382-
// }
360+
_ => {}
383361
}
384362

385363
walk::walk_member_expression(self, it);
@@ -444,7 +422,6 @@ where
444422
// do not walk further, we don't want to rewrite the identifiers
445423
}
446424

447-
// #[cfg(feature = "debug")]
448425
fn visit_try_statement(&mut self, it: &oxc::ast::ast::TryStatement<'data>) {
449426
// for debugging we need to know what the error was
450427

@@ -463,18 +440,19 @@ where
463440
return;
464441
}
465442

466-
dbg!(&it);
467443
if let Some(h) = &it.handler {
468444
if let Some(p) = &h.param {
469445
let mut restids: Vec<Atom<'data>> = Vec::new();
470446
let mut location_assigned: bool = false;
471447

472-
self.recurse_binding_pattern(&p.pattern, &mut restids, &mut location_assigned);
448+
// variables defined in catch shadow the global, don't rewrite location to the temploc here
449+
self.recurse_binding_pattern(&p.pattern, &mut restids, false, &mut location_assigned);
473450
self.jschanges.add(rewrite!(
474451
h.body.body[0].span(),
475452
CleanFunction {
476453
restids,
477454
expression: false,
455+
location_assigned,
478456
}
479457
));
480458
}
@@ -505,7 +483,8 @@ where
505483
let mut restids: Vec<Atom<'data>> = Vec::new();
506484
let mut location_assigned: bool = false;
507485
for param in &it.params.items {
508-
self.recurse_binding_pattern(&param.pattern, &mut restids, &mut location_assigned);
486+
// function params shadow global, don't rewrite temploc
487+
self.recurse_binding_pattern(&param.pattern, &mut restids, false, &mut location_assigned);
509488
}
510489

511490
if let Some(b) = &it.body {
@@ -516,7 +495,8 @@ where
516495
Span::new(span.start, span.start),
517496
CleanFunction {
518497
restids,
519-
expression: false
498+
expression: false,
499+
location_assigned,
520500
}
521501
));
522502
}
@@ -529,7 +509,7 @@ where
529509
let mut restids: Vec<Atom<'data>> = Vec::new();
530510
let mut location_assigned: bool = false;
531511
for param in &it.params.items {
532-
self.recurse_binding_pattern(&param.pattern, &mut restids, &mut location_assigned);
512+
self.recurse_binding_pattern(&param.pattern, &mut restids, false, &mut location_assigned);
533513
}
534514

535515
walk::walk_function_body(self, &it.body);
@@ -539,6 +519,7 @@ where
539519
CleanFunction {
540520
restids,
541521
expression: it.expression,
522+
location_assigned,
542523
}
543524
));
544525
}
@@ -554,20 +535,6 @@ where
554535
walk::walk_function_body(self, it);
555536
}
556537

557-
fn visit_return_statement(&mut self, it: &ReturnStatement<'data>) {
558-
// if let Some(arg) = &it.argument {
559-
// self.jschanges.insert(JsChange::GenericChange {
560-
// span: Span::new(it.span.start + 6, it.span.start + 6),
561-
// text: format!(" $scramdbg((()=>{{ try {{return arguments}} catch(_){{}} }})(),("),
562-
// });
563-
// self.jschanges.insert(JsChange::GenericChange {
564-
// span: Span::new(expression_span(arg).end, expression_span(arg).end),
565-
// text: format!("))"),
566-
// });
567-
// }
568-
walk::walk_return_statement(self, it);
569-
}
570-
571538
fn visit_unary_expression(&mut self, it: &UnaryExpression<'data>) {
572539
if matches!(it.operator, UnaryOperator::Typeof) {
573540
match it.argument {
@@ -617,21 +584,26 @@ where
617584
return;
618585
}
619586

587+
// (const/let) location = ... is perfectly fine, no matter the scope
588+
// var location = ... is dangerous, it will assign to the real global if called in scope
589+
let shadows = matches!(it.kind, VariableDeclarationKind::Var);
590+
620591
let mut restids: Vec<Atom<'data>> = Vec::new();
621592
let mut location_assigned: bool = false;
622593

623594
for declaration in &it.declarations {
624595
if let Some(e) = &declaration.init {
625596
walk::walk_expression(self, e);
626597
}
627-
self.recurse_binding_pattern(&declaration.id, &mut restids, &mut location_assigned);
598+
self.recurse_binding_pattern(&declaration.id, &mut restids, shadows, &mut location_assigned);
628599
}
629600

630601
self.jschanges.add(rewrite!(
631602
Span::new(it.span.end, it.span.end),
632603
CleanFunction {
633604
restids,
634605
expression: false,
606+
location_assigned,
635607
}
636608
));
637609
}
@@ -640,7 +612,8 @@ where
640612
match &it.left {
641613
AssignmentTarget::AssignmentTargetIdentifier(s) => {
642614
// location = ...
643-
if ["location"].contains(&s.name.to_string().as_str()) {
615+
// location is the only unsafe global that has a setter
616+
if &s.name == "location" {
644617
self.jschanges.add(rewrite!(
645618
it.span,
646619
Assignment {

0 commit comments

Comments
 (0)