~ubuntu-branches/ubuntu/feisty/firefox/feisty-security

« back to all changes in this revision

Viewing changes to extensions/java/xpcom/nsJavaWrapper.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2007-10-19 01:09:21 UTC
  • mfrom: (1.1.18 upstream)
  • Revision ID: james.westby@ubuntu.com-20071019010921-8sglgxbi6kj1pemg
Tags: 2.0.0.8+1nobinonly-0ubuntu1
* New security/stability upstream release (v2.0.0.8)
* MFSA 2007-29 aka CVE-2007-5339 (browser), CVE-2007-5340 (javascript)
* MFSA 2007-30 aka CVE-2007-1095
* MFSA 2007-31 aka CVE-2007-2292
* MFSA 2007-32 aka CVE-2007-3511, CVE-2006-2894
* MFSA 2007-33 aka CVE-2007-5334
* MFSA 2007-34 aka CVE-2007-5337
* MFSA 2007-35 aka CVE-2007-5338
* MFSA 2007-36 aka CVE-2007-4841 (windows only)

Show diffs side-by-side

added added

removed removed

Lines of Context:
883
883
      break;
884
884
    }
885
885
 
 
886
    case nsXPTType::T_PSTRING_SIZE_IS:
 
887
    case nsXPTType::T_PWSTRING_SIZE_IS:
 
888
    {
 
889
      NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
 
890
      
 
891
      LOG(("Sized string\n"));
 
892
      jstring data = nsnull;
 
893
      if (!aIsOut) {  // 'in'
 
894
        data = (jstring) aParam;
 
895
      } else if (aParam) {  // 'inout'
 
896
        data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam,
 
897
                                                    aIndex);
 
898
      }
 
899
 
 
900
      PRUint32 length = 0;
 
901
      if (data) {
 
902
        if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
 
903
          length = env->GetStringUTFLength(data);
 
904
        } else {
 
905
          length = env->GetStringLength(data);
 
906
        }
 
907
        if (length > aArraySize) {
 
908
          rv = NS_ERROR_ILLEGAL_VALUE;
 
909
          break;
 
910
        }
 
911
      }
 
912
 
 
913
      PRUint32 size_of_char = (aType == nsXPTType::T_PSTRING_SIZE_IS) ?
 
914
                              sizeof(char) : sizeof(jchar);
 
915
      PRUint32 allocLength = (aArraySize + 1) * size_of_char;
 
916
      void* buf = nsMemory::Alloc(allocLength);
 
917
      if (!buf) {
 
918
        rv = NS_ERROR_OUT_OF_MEMORY;
 
919
        break;
 
920
      }
 
921
 
 
922
      if (data) {
 
923
        if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
 
924
          const char* str = env->GetStringUTFChars(data, nsnull);
 
925
          if (!str) {
 
926
            nsMemory::Free(buf);
 
927
            rv = NS_ERROR_OUT_OF_MEMORY;
 
928
            break;
 
929
          }
 
930
          memcpy(buf, str, length);
 
931
          env->ReleaseStringUTFChars(data, str);
 
932
        } else {
 
933
          jchar* jchar_str = NS_STATIC_CAST(jchar*, buf);
 
934
          env->GetStringRegion(data, 0, length, jchar_str);
 
935
        }
 
936
      }
 
937
      
 
938
      aVariant.val.p = buf;
 
939
      if (aIsOut) { // 'inout'
 
940
        aVariant.ptr = &aVariant.val;
 
941
        aVariant.SetPtrIsData();
 
942
      }
 
943
 
 
944
      break;
 
945
    }
 
946
 
886
947
    default:
887
948
      NS_WARNING("unexpected parameter type");
888
949
      return NS_ERROR_UNEXPECTED;
1234
1295
      // cleanup
1235
1296
      // If this is not an out param or if the invokeResult is a failure case,
1236
1297
      // then the array elements have not been cleaned up.  Do so now.
1237
 
      if (!aParamInfo.IsOut() || NS_FAILED(aInvokeResult)) {
 
1298
      if (!aParamInfo.IsOut() || (NS_FAILED(aInvokeResult) && aVariant.val.p)) {
1238
1299
        nsXPTCVariant var;
1239
1300
        for (PRUint32 i = 0; i < aArraySize; i++) {
1240
1301
          rv = GetNativeArrayElement(aArrayType, aVariant.val.p, i, &var);
1248
1309
      break;
1249
1310
    }
1250
1311
 
 
1312
    case nsXPTType::T_PSTRING_SIZE_IS:
 
1313
    case nsXPTType::T_PWSTRING_SIZE_IS:
 
1314
    {
 
1315
      NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
 
1316
 
 
1317
      if ((aParamInfo.IsOut()) && NS_SUCCEEDED(aInvokeResult))
 
1318
      {
 
1319
        // create new string from data
 
1320
        jstring str = nsnull;
 
1321
        if (aVariant.val.p) {
 
1322
          if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
 
1323
            PRUint32 len = (aArraySize + 1) * sizeof(char);
 
1324
            char* buf = (char*) nsMemory::Alloc(len);
 
1325
            if (buf) {
 
1326
              memcpy(buf, aVariant.val.p, len);
 
1327
              buf[aArraySize] = '\0';
 
1328
              str = env->NewStringUTF((const char*) buf);
 
1329
              nsMemory::Free(buf);
 
1330
            }
 
1331
          } else {
 
1332
            str = env->NewString((const jchar*) aVariant.val.p, aArraySize);
 
1333
          }
 
1334
          if (!str) {
 
1335
            rv = NS_ERROR_OUT_OF_MEMORY;
 
1336
            break;
 
1337
          }
 
1338
        }
 
1339
 
 
1340
        if (aParamInfo.IsRetval()) {
 
1341
          *aParam = str;
 
1342
        } else if (*aParam) {
 
1343
          // put new string into output array
 
1344
          env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, str);
 
1345
        }
 
1346
      }
 
1347
 
 
1348
      // cleanup
 
1349
      if (aVariant.val.p)
 
1350
        nsMemory::Free(aVariant.val.p);
 
1351
      break;
 
1352
    }
 
1353
 
1251
1354
    default:
1252
1355
      NS_WARNING("unexpected parameter type");
1253
1356
      return NS_ERROR_UNEXPECTED;
1405
1508
    }
1406
1509
    memset(params, 0, paramCount * sizeof(nsXPTCVariant));
1407
1510
 
 
1511
    PRBool foundDependentParam = PR_FALSE;
1408
1512
    for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
1409
1513
    {
1410
1514
      LOG(("\t Param %d: ", i));
1411
1515
      const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
1412
1516
      params[i].type = paramInfo.GetType();
1413
1517
 
 
1518
      if (params[i].type.IsDependent() && paramInfo.IsIn()) {
 
1519
        foundDependentParam = PR_TRUE;
 
1520
        continue;
 
1521
      }
 
1522
      
1414
1523
      if (paramInfo.IsIn()) {
1415
1524
        PRUint8 type = params[i].type.TagPart();
1416
1525
 
1417
 
        // is paramater an array?
1418
 
        PRUint8 arrayType = 0;
1419
 
        PRUint32 arraySize = 0;
1420
 
        if (type == nsXPTType::T_ARRAY) {
1421
 
          // get array type
1422
 
          nsXPTType xpttype;
1423
 
          rv = iinfo->GetTypeForParam(methodIndex, &paramInfo, 1, &xpttype);
1424
 
          if (NS_FAILED(rv))
1425
 
            break;
1426
 
          arrayType = xpttype.TagPart();
1427
 
 
1428
 
          // get size of array
1429
 
          PRUint8 argnum;
1430
 
          rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, &paramInfo, 0,
1431
 
                                                 &argnum);
1432
 
          if (NS_FAILED(rv))
1433
 
            break;
1434
 
          arraySize = params[argnum].val.u32;
1435
 
        }
1436
 
 
1437
1526
        // get IID for interface params
1438
1527
        nsID iid;
1439
 
        if (type == nsXPTType::T_INTERFACE ||
1440
 
            type == nsXPTType::T_INTERFACE_IS ||
1441
 
            type == nsXPTType::T_ARRAY &&
1442
 
              (arrayType == nsXPTType::T_INTERFACE ||
1443
 
               arrayType == nsXPTType::T_INTERFACE_IS))
1444
 
        {
1445
 
          PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
1446
 
          rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
 
1528
        if (type == nsXPTType::T_INTERFACE) {
 
1529
          rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type,
1447
1530
                                    methodIndex, params, PR_TRUE, iid);
1448
1531
        }
1449
1532
 
1452
1535
          if (aParams && !paramInfo.IsRetval()) {
1453
1536
            param = env->GetObjectArrayElement(aParams, i);
1454
1537
          }
1455
 
          rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
1456
 
                           arraySize, PR_FALSE, 0, params[i]);
 
1538
          rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, 0, 0,
 
1539
                           PR_FALSE, 0, params[i]);
1457
1540
        }
1458
1541
      } else {
1459
1542
        LOG(("out/retval\n"));
1461
1544
        params[i].SetPtrIsData();
1462
1545
      }
1463
1546
    }
 
1547
    
 
1548
    // Handle any dependent params by doing a second pass
 
1549
    if (foundDependentParam) {
 
1550
      
 
1551
      for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++) {
 
1552
        
 
1553
        const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);
 
1554
        params[j].type = paramInfo.GetType();
 
1555
 
 
1556
        if (!params[j].type.IsDependent())
 
1557
          continue;
 
1558
 
 
1559
        if (paramInfo.IsIn()) {
 
1560
          PRUint8 type = params[j].type.TagPart();
 
1561
 
 
1562
          // is paramater an array or sized string?
 
1563
          PRUint8 arrayType = 0;
 
1564
          PRUint32 arraySize = 0;
 
1565
          PRBool isArray = params[j].type.IsArray();
 
1566
          PRBool isSizedString = isArray ? PR_FALSE :
 
1567
                   type == nsXPTType::T_PSTRING_SIZE_IS ||
 
1568
                   type == nsXPTType::T_PWSTRING_SIZE_IS;
 
1569
 
 
1570
          if (isArray) {
 
1571
            // get array type
 
1572
            nsXPTType xpttype;
 
1573
            rv = iinfo->GetTypeForParam(methodIndex, &paramInfo, 1, &xpttype);
 
1574
            if (NS_FAILED(rv))
 
1575
              break;
 
1576
            arrayType = xpttype.TagPart();
 
1577
            // IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
 
1578
            // therefore, treat as a signed 8bit value
 
1579
            if (arrayType == nsXPTType::T_U8)
 
1580
              arrayType = nsXPTType::T_I8;
 
1581
          }
 
1582
 
 
1583
          if (isArray || isSizedString) {
 
1584
            // get size of array or string
 
1585
            PRUint8 argnum;
 
1586
            rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, &paramInfo, 0,
 
1587
                                                   &argnum);
 
1588
            if (NS_FAILED(rv))
 
1589
              break;
 
1590
            arraySize = params[argnum].val.u32;
 
1591
          }
 
1592
 
 
1593
          // get IID for interface params
 
1594
          nsID iid;
 
1595
          if (type == nsXPTType::T_INTERFACE_IS ||
 
1596
              type == nsXPTType::T_ARRAY &&
 
1597
                (arrayType == nsXPTType::T_INTERFACE ||
 
1598
                 arrayType == nsXPTType::T_INTERFACE_IS))
 
1599
          {
 
1600
            PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
 
1601
            rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
 
1602
                                      methodIndex, params, PR_TRUE, iid);
 
1603
          }
 
1604
 
 
1605
          if (NS_SUCCEEDED(rv)) {
 
1606
            jobject param = nsnull;
 
1607
            if (aParams && !paramInfo.IsRetval()) {
 
1608
              param = env->GetObjectArrayElement(aParams, j);
 
1609
            }
 
1610
            rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
 
1611
                             arraySize, PR_FALSE, 0, params[j]);
 
1612
          }
 
1613
        }
 
1614
      }
 
1615
    }
 
1616
    
1464
1617
    if (NS_FAILED(rv)) {
1465
1618
      ThrowException(env, rv, "SetupParams failed");
1466
1619
      return nsnull;
1487
1640
    const nsXPTParamInfo &paramInfo = methodInfo->GetParam(i);
1488
1641
    PRUint8 type = paramInfo.GetType().TagPart();
1489
1642
 
1490
 
    // is paramater an array?
 
1643
    // is paramater an array or sized string?
1491
1644
    PRUint8 arrayType = 0;
1492
1645
    PRUint32 arraySize = 0;
1493
 
    if (type == nsXPTType::T_ARRAY) {
 
1646
    PRBool isArray = params[i].type.IsArray();
 
1647
    PRBool isSizedString = isArray ? PR_FALSE :
 
1648
             type == nsXPTType::T_PSTRING_SIZE_IS ||
 
1649
             type == nsXPTType::T_PWSTRING_SIZE_IS;
 
1650
 
 
1651
    if (isArray) {
1494
1652
      // get array type
1495
1653
      nsXPTType array_xpttype;
1496
1654
      rv = iinfo->GetTypeForParam(methodIndex, &paramInfo, 1, &array_xpttype);
1497
1655
      if (NS_FAILED(rv))
1498
1656
        break;
1499
1657
      arrayType = array_xpttype.TagPart();
 
1658
      // IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
 
1659
      // therefore, treat as a signed 8bit value
 
1660
      if (arrayType == nsXPTType::T_U8)
 
1661
        arrayType = nsXPTType::T_I8;
 
1662
    }
1500
1663
 
 
1664
    if (isArray || isSizedString) {
1501
1665
      // get size of array
1502
1666
      PRUint8 argnum;
1503
1667
      rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, &paramInfo, 0,
1530
1694
    rv = FinalizeParams(env, paramInfo, type, params[i], iid, PR_FALSE,
1531
1695
                        arrayType, arraySize, 0, invokeResult, javaElement);
1532
1696
  }
1533
 
  if (NS_FAILED(rv)) {
1534
 
    ThrowException(env, rv, "FinalizeParams failed");
1535
 
    return nsnull;
1536
 
  }
1537
1697
 
1538
1698
  // Normally, we would delete any created nsID object in the above loop.
1539
1699
  // However, GetIIDForMethodParam may need some of the nsID params when it's
1540
1700
  // looking for the IID of an INTERFACE_IS.  Therefore, we can't delete it
1541
1701
  // until we've gone through the 'Finalize' loop once and created the result.
1542
 
  for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++)
 
1702
  for (PRUint8 j = 0; j < paramCount; j++)
1543
1703
  {
1544
1704
    const nsXPTParamInfo &paramInfo = methodInfo->GetParam(j);
1545
1705
    const nsXPTType &type = paramInfo.GetType();
1561
1721
    message.AppendLiteral("\" returned an error condition");
1562
1722
    ThrowException(env, invokeResult, message.get());
1563
1723
  }
 
1724
  if (NS_FAILED(rv)) {
 
1725
    ThrowException(env, rv, "FinalizeParams failed");
 
1726
    return nsnull;
 
1727
  }
1564
1728
 
1565
1729
  LOG(("<=== (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));
1566
1730
  return result;